คำสั่งไปยังแท็บเค้าโครงรายการแยกกันอย่าง


39

บางครั้งฉันได้รับเป็นรายการคั่นแท็บป้อนข้อมูลซึ่งไม่ได้จัดแนวค่อนข้างเช่น

var1  var2  var3
var_with_long_name_which_ruins_alignment  var2 var3

มีวิธีง่าย ๆ ในการเรนเดอร์แบบเรียงซ้อนหรือไม่?

var1                                      var2  var3
var_with_long_name_which_ruins_alignment  var2  var3

ใครบางคนสามารถสร้างโซลูชันขึ้นอยู่กับแท็บที่ยืดหยุ่น: nickgravgaard.com/elastictabstops
Mikel


และการนำไปใช้งาน: golang.org/pkg/tabwriter
มิเคล

16
พยายามไปที่ท่อcolumn -tหรือไม่
alex

7
ซุกในตอนท้ายของคำตอบของมิเคลคือความคิดเห็นที่พับหัว (โดยมิเคล) ... columns -tทำหน้าที่ในพื้นที่ว่างทั่วไป ในการทำงานกับแท็บเท่านั้นให้ใช้column -t -s $'\t'
Peter.O

คำตอบ:


51

ดังนั้นคำตอบคือ:

column -t file_name

โปรดทราบว่าสิ่งนี้จะแยกคอลัมน์ที่ช่องว่างใด ๆไม่ใช่แค่แท็บ หากคุณต้องการแยกแท็บเท่านั้นให้ใช้:

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

การ-s $'\t'ตั้งค่าตัวคั่นเป็นแท็บเท่านั้นและ-nรักษาคอลัมน์ว่าง (แท็บที่อยู่ติดกัน)

PS: เพียงแค่ต้องการชี้ให้เห็นว่าเครดิตไปอเล็กซ์เช่นกัน เขาให้คำแนะนำดั้งเดิมว่าเป็นความคิดเห็นต่อคำถาม แต่ไม่เคยโพสต์เป็นคำตอบ


ฉันจะรอสักครู่เพื่อให้อเล็กซ์ได้รับเครดิตฉันคิดว่าเขาสมควรได้รับมัน หากเขาไม่ตอบในสองสามวันฉันจะยอมรับคำตอบจากคนอื่น
Elazar Leibovich

แน่นอน! ฉันก็ไม่รู้เหมือนกันcolumn:)
บารัน

1
ดูเหมือนว่าจะเหมาะ แต่น่าเสียดายcolumnที่ล้มเหลวเมื่อพบเซลล์ว่าง ดูโพสต์นี้ columnคุณอาจสามารถระบุ-nตัวเลือกเพื่อแก้ไขสิ่งนี้ทั้งนี้ขึ้นอยู่กับรุ่นของคุณ
John J. Camilleri

นอกจากนี้คำสั่งนี้จะไม่เพียง แต่แยกบนแท็บ แต่ยังใน "ช่องว่างใด ๆ " column -t -s $'\t'ที่จะแยกเพียงบนแท็บการใช้งาน
ฟริตซ์

3

นี่คือสคริปต์ที่ต้องทำ:

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";
}

การใช้

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

อืมขอบคุณ แต่ฉันหวังว่าจะมีวิธี "พกพา" มากกว่านี้
Elazar Leibovich

ฉันด้วย! หาไม่เจอ prและnlเป็นสองเครื่องมือพื้นฐานสำหรับการจัดรูปแบบและหลังจากนั้นawk, sed, perlฯลฯ
มิเกล

1
มันง่ายเหมือนcolumn
Elazar Leibovich

2
@Elzar ยอดเยี่ยม! column -t -s $'\t'ดูเหมือนว่าจะทำงาน
มิเคล

3

สำหรับแท็บหยุดด้วยตนเอง: expand -t 42,48

สำหรับการหยุดแท็บอัตโนมัติตามที่alexแนะนำ:column -t

( expandอยู่ในระบบ POSIX ทั้งหมดcolumnเป็นยูทิลิตี้ BSD ซึ่งมีอยู่ในลีนุกซ์หลายรุ่นเช่นกัน)


1

จากความคิดเห็นของ Peter.O ซึ่งเป็นสิ่งที่ฉันต้องการจัดเรียง (ข้อมูลคั่นด้วยแท็บ TSV) วลีนี้ใช้งานได้ดีมาก:

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

คำอธิบาย:

Sed จะเพิ่มช่องว่างระหว่างตัวคั่นว่าง

คอลัมน์จะเพิ่มระยะห่างเท่ากันระหว่างคอลัมน์

zydsld|asl|asd
das|aosdk|dd

กลายเป็น

zydsld|asl  |asd
das   |aosdk|dd 

Less จะเปิดเอาต์พุตในวิวเวอร์ไฟล์ -N และ -S จะเพิ่มหมายเลขบรรทัดและปิดการใช้งานการตัดตามลำดับ


1
คำตอบแบบบรรทัดเดียวมักไม่เป็นประโยชน์มากที่สุด ลองขยายโพสต์ของคุณเพื่อรวมคำอธิบายโซลูชันของคุณหรือเอกสารที่รองรับ
HalosGhost

0

ด้วยมิลเลอร์ ( http://johnkerl.org/miller/doc ) คุณมีผลงานพิมพ์ที่น่ารัก

วิ่ง

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

เพื่อที่จะมี

var1                                     var2 var3
var_with_long_name_which_ruins_alignment var2 var3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.