lệnh để bố trí tab tách biệt danh sách độc đáo


39

Đôi khi, tôi nhận được như là một danh sách tách biệt tab đầu vào, chẳng hạn như không được căn chỉnh

var1  var2  var3
var_with_long_name_which_ruins_alignment  var2 var3

Có một cách dễ dàng để làm cho chúng phù hợp?

var1                                      var2  var3
var_with_long_name_which_ruins_alignment  var2  var3

Ai đó có thể thực hiện một giải pháp dựa trên các tab
Mikel


Và triển khai Go: golang.org/pkg/tabwriter
Mikel

16
Đã thử đường ống đến column -t?
alex

7
Ẩn giấu ở cuối câu trả lời perl của Mikel là bình luận móc sắt (của Mikel) ... columns -thành động trên khoảng trắng chung. Để chỉ hoạt động với các tab , hãy sử dụngcolumn -t -s $'\t'
Peter.O

Câu trả lời:


51

Vì vậy, câu trả lời trở thành:

column -t file_name

Lưu ý rằng điều này phân chia các cột ở bất kỳ khoảng trắng nào , không chỉ các tab. Nếu bạn chỉ muốn tách trên các tab, hãy sử dụng:

column -t -s $'\t' -n file_name

Các -s $'\t'bộ dấu phân cách các tab chỉ và -nbảo tồn trống cột (tab liền kề).

PS: Chỉ muốn chỉ ra rằng tín dụng cũng dành cho Alex . Gợi ý ban đầu được ông cung cấp như một bình luận cho câu hỏi, nhưng không bao giờ được đăng dưới dạng câu trả lời.


Tôi sẽ đợi Alex một chút để nhận được tín dụng, tôi nghĩ anh ấy xứng đáng với điều đó. Nếu anh ấy không trả lời trong vài ngày nữa, tôi sẽ chấp nhận câu trả lời từ người khác.
Elazar Leibovich

Chắc chắn rồi! Tôi cũng không biết column:)
Barun

1
Điều này có vẻ lý tưởng nhưng không may columndường như thất bại khi nó gặp các ô trống. Xem bài này . Tùy thuộc vào phiên bản nào của columnbạn, bạn có thể chỉ định -ntùy chọn để sửa lỗi này.
John J. Camilleri

Ngoài ra, lệnh này sẽ không chỉ phân chia trên các tab, mà còn trên "bất kỳ khoảng trắng" nào. Để phân chia chỉ trên các tab, sử dụng column -t -s $'\t'.
Fritz

3

Đây là một kịch bản để làm điều đó:

aligntabs.pl

#!/usr/bin/perl

my $delim = '\s*\t\s*';

my %length = ();
my @lines = ();
for my $line (<>) {
    chomp $line;
    my @words = split $delim, $line;
    my $numwords = scalar(@words);
    for my $i (0..$numwords-1) {
        my $maxlen = $length{$i} // 0;
        my $thislen = length($words[$i]);
        $maxlen = ($thislen > $maxlen)? $thislen: $maxlen;
        $length{$i} = $maxlen;
    }
    push @lines, [@words];
}

foreach my $wordsref (@lines) {
    my @words = @$wordsref;
    my $numwords = scalar(@words);
    for my $i (0..$numwords-1) {
        if ($i < $numwords-1) {
            my $fieldlen = $length{$i};
            printf "%-${fieldlen}s ", $words[$i];
        }
        else {
            print $words[$i];
        }
    }
    print "\n";
}

sử dụng

$ aligntabs.pl < infile
var1                                     var2 var3
var_with_long_name_which_ruins_alignment var2 var3

Ừm, cảm ơn, nhưng tôi đã hy vọng có một cách "di động" hơn để làm điều đó.
Elazar Leibovich

Tôi cũng vậy! Không thể tìm thấy một. prnllà hai công cụ cơ bản cho các định dạng, và sau đó awk, sed, perlvv
Mikel

1
nó đơn giản nhưcolumn
Elazar Leibovich

2
@Elzar Tuyệt vời! column -t -s $'\t'dường như làm công việc
Mikel

3

Đối với các điểm dừng thủ công: expand -t 42,48

Đối với các điểm dừng tự động, như được đề xuất bởi alex :column -t

( expandcó trên tất cả các hệ thống POSIX. columnLà một tiện ích BSD, cũng có sẵn trong nhiều bản phân phối Linux.)


1

Theo dõi từ nhận xét của Peter.O, đó là điều tôi muốn căn chỉnh (dữ liệu được phân tách bằng tab, TSV), cụm từ này hoạt động rất độc đáo:

column -t -s $'\t' /Users/me/data.csv | less --chop-long-lines

0
sed 's/||/| |/g;s/||/| |/g' filename-here | column -s"|" -t | less -#2 -N -S

Giải trình:

Sed sẽ thêm một khoảng trống giữa các dấu phân cách trống

Cột sẽ thêm khoảng cách bằng nhau giữa các cột

zydsld|asl|asd
das|aosdk|dd

trở thành

zydsld|asl  |asd
das   |aosdk|dd 

Ít hơn sẽ mở đầu ra trong một trình xem tập tin. -N và -S sẽ thêm số dòng và vô hiệu hóa gói tương ứng


1
Câu trả lời một dòng thường không hữu ích nhất. Xem xét mở rộng bài đăng của bạn để bao gồm giải thích về giải pháp của bạn hoặc tài liệu hỗ trợ nó.
HalosGhost

0

Với Miller ( http://johnkerl.org/miller/doc ) bạn có đầu ra in đẹp.

Chạy

mlr --inidx --ifs "\t" --opprint cat input | tail -n +2

var1                                     var2 var3
var_with_long_name_which_ruins_alignment var2 var3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.