การเรียงลำดับไฟล์ที่คั่นด้วยแท็บ


180

ฉันมีข้อมูลในรูปแบบต่อไปนี้:

foo<tab>1.00<space>1.33<space>2.00<tab>3

ตอนนี้ฉันพยายามเรียงลำดับไฟล์ตามฟิลด์สุดท้ายลดลง ฉันลองคำสั่งต่อไปนี้ แต่มันไม่ได้เรียงตามที่เราคาดไว้

$ sort -k3nr file.txt  # apparently this sort by space as delimiter

$ sort -t"\t" -k3nr file.txt
  sort: multi-character tab `\\t'

$ sort -t "`/bin/echo '\t'`" -k3,3nr file.txt
  sort: multi-character tab `\\t'

วิธีที่ถูกต้องในการทำคืออะไร?

นี่คือข้อมูลตัวอย่าง

คำตอบ:


312

ใช้ทุบตีนี้จะทำเคล็ดลับ:

$ sort -t$'\t' -k3 -nr file.txt

สังเกตเครื่องหมายดอลลาร์ที่อยู่ด้านหน้าของสตริงที่มีเครื่องหมายคำพูดเดี่ยว คุณสามารถอ่านเกี่ยวกับเรื่องนี้ในQuoting ส่วน ANSI-C ของทุบตีหน้าคน


2
ใช้ '"'"'เพื่อใช้ภายในนามแฝง
ปาโบล

คุณสามารถแสดงวิธีส่ง delimeter นี้เพื่อจัดเรียงภายในคำสั่ง awk ได้หรือไม่? เช่นเดียวกับในawk '{print $0 | "sort -nr" > "outfile" }' datafileยกเว้นด้วย delimeter แท็บที่ใช้ Escape ที่ส่งไปยังคำสั่ง sort
เมอร์ลิน

11

ตามค่าเริ่มต้นตัวคั่นฟิลด์จะไม่ว่างเปล่าเป็นการเปลี่ยนว่างเปล่าดังนั้นแท็บควรทำงานได้ดี

อย่างไรก็ตามคอลัมน์นั้นถูกจัดทำดัชนีฐาน 1 และฐาน 0 ดังนั้นคุณอาจต้องการ

sort -k4nr file.txt

เพื่อเรียงลำดับ file.txt ตามคอลัมน์ 4 เป็นตัวเลขในลำดับย้อนกลับ (แม้ว่าข้อมูลในคำถามจะมี 5 ฟิลด์ดังนั้นฟิลด์สุดท้ายจะเป็นดัชนี 5)


4
วิธีนี้จะใช้งานได้หากจำนวนอักขระเว้นวรรคระหว่างฟิลด์ที่คั่นด้วยแท็บเหมือนกันสำหรับทุกบรรทัดอินพุต
ลาร์ส Haugseth

5

คุณต้องใส่อักขระแท็บจริงหลังจาก -t \ และเพื่อทำเช่นนั้นในเชลล์คุณกด ctrl-v และอักขระแท็บ กระสุนส่วนใหญ่ที่ฉันใช้สนับสนุนโหมดของรายการแท็บตัวอักษรนี้

อย่างไรก็ตามระวังเนื่องจากการคัดลอกและวางจากที่อื่นโดยทั่วไปจะไม่เก็บแท็บไว้


นี่คือคำตอบที่ดีที่สุด (พกพามากที่สุด) emacs ยังให้คุณทำเช่นนั้นในโหมด 'insert insert': C-q <tab>ตัวอย่างเช่น ฉันคิดว่ามันเป็นแบบ^Vนาโนเช่นกัน
Wyatt8740

3

โซลูชัน $ ไม่ทำงานสำหรับฉัน อย่างไรก็ตามโดยการใส่อักขระแท็บในคำสั่งได้จริง: sort -t '' -k2


1
ใช้<C-v><Tab>เพื่อแทรกแท็บในกรณีที่ใช้คีย์แท็บสำหรับการเติมข้อมูลอัตโนมัติในเชลล์ของคุณ
JúdaRonén

1
การอ้างถึง ANSI $'\t'ทำงานเป็น ksh, zsh และ bash Bourne shell ไม่รองรับ ดูโพสต์นี้: unix.stackexchange.com/a/371873/201820
codeforester

1

awk '{ print print $1"\t"$2"\t"$3"\t"$4"\t"$5 }'ท่อมันผ่านสิ่งที่ต้องการ การดำเนินการนี้จะเปลี่ยนช่องว่างเป็นแท็บ


@MB: ฉันต้องการให้พื้นที่ยังคงเหมือนเดิม
neversaint

1
มีวิธีที่สะอาดกว่าที่จะทำอย่างแน่นอน แต่ไม่มีสิ่งใดที่จะป้องกันไม่ให้คุณทำการไพพ์ผ่าน awk เปลี่ยนช่องว่างเป็นแท็บเรียงลำดับข้อมูล
Michiel Buddingh

1
สิ่งนี้จะไม่ทำงานหากมีแท็บและช่องว่างหลายแบบผสมกันซึ่งคุณต้องการรักษาไว้
James Thompson

1

โดยทั่วไปการเก็บข้อมูลเช่นนี้ไม่ใช่สิ่งที่ดีหากคุณสามารถหลีกเลี่ยงได้เพราะผู้คนมักสับสนกับแท็บและช่องว่าง

การแก้ปัญหาของคุณนั้นตรงไปตรงมามากในภาษาสคริปต์เช่น Perl, Python หรือ Ruby นี่คือตัวอย่างรหัส:

#!/usr/bin/perl -w

use strict;

my $sort_field = 2;
my $split_regex = qr{\s+};

my @data;
push @data, "7 8\t 9";
push @data, "4 5\t 6";
push @data, "1 2\t 3";

my @sorted_data = 
    map  { $_->[1] }
    sort { $a->[0] <=> $b->[0] }
    map  { [ ( split $split_regex, $_ )[$sort_field], $_ ] }
    @data;

print "unsorted\n";
print join "\n", @data, "\n";
print "sorted by $sort_field, lines split by $split_regex\n";
print join "\n", @sorted_data, "\n";

1

ฉันต้องการโซลูชันสำหรับการจัดเรียง Gnu บน Windows แต่ไม่มีวิธีแก้ปัญหาใดที่ใช้ได้สำหรับฉันในบรรทัดคำสั่ง

ด้วยการใช้เบาะแสของ Lloyd ไฟล์แบทช์ (.bat) ต่อไปนี้ใช้ได้สำหรับฉัน

พิมพ์อักขระแท็บภายในเครื่องหมายคำพูดคู่

C:\>cat foo.bat

sort -k3 -t"    " tabfile.txt

1
ใช่เคล็ดลับที่นี่มีการวางไว้ในไฟล์ค้างคาวมิฉะนั้นมันจะไม่ทำงาน
คาร์ลอเรนดอน

1

ฉันมีปัญหานี้กับการเรียงลำดับใน cygwin ในเปลือกทุบตีเมื่อใช้ 'ทั่วไปตัวเลขเรียงลำดับ' ถ้าฉันระบุ-t$'\t' -kFgโดยที่ F คือหมายเลขฟิลด์มันจะไม่ทำงาน แต่เมื่อฉันระบุทั้งสอง-t$'\t'และ-kF,Fg(เช่น-k7,7gสำหรับฟิลด์ที่ 7) จะใช้งานได้ -kF,Fgโดยไม่ต้อง-t$'\t'ไม่ได้ทำงาน


0

หากคุณต้องการทำให้ง่ายขึ้นด้วยตัวคุณเองโดยมีเพียงแท็บให้แทนที่ช่องว่างด้วยแท็บ:

tr " " "\t" < <file> | sort <options>

TR ของฉันไม่อ่านไฟล์มีเพียงสตรีม XD usage: tr [-Ccsu] string1 string2
Cat Unfun

1
tr string1 string2 <some-file. ทุกอย่างสามารถอ่านไฟล์ได้ตราบเท่าที่สามารถอ่าน stdin ได้
Randal Schwartz

0

คำตอบ Lars Haugseth ใช้ได้เฉพาะจากบรรทัดคำสั่งสำหรับฉันซึ่งจะให้ข้อผิดพลาดนี้หากดำเนินการจากเชลล์สคริปต์:

จัดเรียง: แท็บหลายอักขระ '$ \ t'

วิธีการแก้ปัญหาถ้ามันเขียนรหัสในเชลล์สคริปต์ถ้าใครดูเป็น

sort -t'    '

อักขระแท็บอยู่ระหว่างเครื่องหมายคำพูด

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