จัดเรียงไฟล์ CSV ตามลำดับความสำคัญของคอลัมน์โดยใช้คำสั่ง "sort"


95

ฉันมีไฟล์ csv และต้องการจัดเรียงตามลำดับความสำคัญของคอลัมน์เช่น "เรียงตาม" ตัวอย่างเช่น:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

หากสถานการณ์นี้เป็นผลมาจาก "เลือก" "ลำดับตาม" จะเป็นดังนี้: เรียงลำดับตามคอลัมน์ 2 คอลัมน์ 1 คอลัมน์ 3 ผลลัพธ์จะเป็น:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

ฉันต้องการทราบวิธีรับผลลัพธ์เดียวกันนี้โดยใช้คำสั่ง "sort" ใน Unix


4
อย่างไรก็ตามนั่นคือไฟล์ ssv (ค่าที่คั่นด้วยอัฒภาค): P
John Strood

คำตอบ:


157
sort --field-separator=';' --key=2,1,3

9
หากค่าเป็นตัวเลขคุณอาจต้องการพิจารณาใช้-nตัวเลือกซึ่งจะ "เปรียบเทียบตามค่าตัวเลขสตริง" หรือ-gตัวเลือกที่ "เปรียบเทียบตามค่าตัวเลขทั่วไป" 1,10,2,20การเปรียบเทียบสตริงของค่าตัวเลขจะได้รับหมายเลขสั่งเช่น อย่างน้อยก็เป็นตัวเลือกที่มีอยู่ในเวอร์ชันการจัดเรียงของฉันบน CentOS คุณควรตรวจสอบกับหน้าคนว่าตัวเลือกที่ถูกต้องในเวอร์ชันการจัดเรียงของคุณคืออะไร
Adam Porad

5
ฉันได้รับsort: stray character in field spec: invalid field specification ‘2,1,3’
Martin Thoma

3
อย่างไรก็ตามsort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csvทำงานให้ฉัน
Martin Thoma

6
@MartinThoma จะได้รับเป็นเวลานาน sort --field-separator=';' --key={2,1,3}แต่ฉันวิ่งเข้าไปในปัญหาของคุณและฉันพบว่า สิ่งนี้เริ่มทำงานGNU coreutils 8.4ตั้งแต่เดือนเมษายน 2559
mrbolichi

3
@mrbolichi สัญกรณ์--key={2,1,3}ใช้การขยายตัวของ bash
kvantour

29

สมมติว่าคุณมีแถวอื่น3;10;3ในunsorted.csvไฟล์ของคุณ จากนั้นฉันเดาว่าคุณคาดหวังผลลัพธ์ที่เรียงตามตัวเลข:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

และไม่เรียงตามตัวอักษร:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

เพื่อให้ได้สิ่งนั้นคุณต้องใช้-n:

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

เป็นมูลค่าการกล่าวขวัญที่2,2ต้องใช้ ถ้าใช้เท่านั้น2ให้sortใช้สตริงจากจุดเริ่มต้นของฟิลด์ 2 ไปยังจุดสิ้นสุด 2,2ทำให้แน่ใจว่าข้อมูลเพียง2ถูกนำมาใช้


8
ตัวชี้ความแตกต่างระหว่าง -k 2 และ -k 2,2 มีนัยสำคัญ! ฉันมองข้ามเรื่องนี้ไปแล้วในการอ่านครั้งแรกของ man page ขอบคุณ.
usonianhorizon

ฉันเพิ่มแถวพิเศษบาง3;10;3, 3:10:5, 3:10;2, 3;10;3ในการสั่งซื้อในแฟ้มแหล่งที่มาและเมื่อใช้เพียงแค่ -k 2,2ดูเหมือนว่ามันจะเรียงลำดับในคอลัมน์ที่ 2 และ 3 "The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal."หน้าคนพูดว่า ในกรณีของฉันคีย์ก่อนหน้านี้ (ค่า = 10) เปรียบเทียบเท่ากันอย่างไรก็ตามฉันไม่ได้ระบุ-kหลายครั้ง ฉันไม่แน่ใจว่านี่เป็นพฤติกรรมที่เชื่อถือได้หรือเกี่ยวข้องกับระบบของฉัน (mac) ในที่สุดมันก็ไม่สำคัญตราบใดที่การเรียงลำดับหลักถูกต้อง
Davos

โอ้ฉันเห็นว่ายัง-sมีการเรียงลำดับที่มั่นคงซึ่งไม่สนใจคีย์ที่เท่ากันซึ่งเห็นได้ชัดว่าเร็วกว่าตามมนุษย์
Davos

24

คำตอบของ Charlie ข้างต้นไม่ได้ผลสำหรับฉันใน Cygwin (เรียงลำดับเวอร์ชัน 2.0, GNU textutils) สิ่งต่อไปนี้ทำ:

sort -t"," -k2 -k1 -k1

3
Cygwin มีการเรียงลำดับเวอร์ชันเก่ากว่า เช่นเคยเพจคนเป็นเพื่อนคุณ
Charlie Martin

2
ฉันเห็นด้วยกับ @CharlieMartin คุณควรตรวจสอบหน้าคนในระบบของคุณ ใน CentOS ฉันใช้sort --field-separator=';' -k2 -k1 -k3 test.csv
Adam Porad

-6

.. และหากใครก็ตามที่ทำตามคำสั่ง 'sort' แต่ตอนนี้ต้องการรับรายการที่ไม่ซ้ำกันมากกว่ารายการเดียวต่อบรรทัด (เช่นจำนวน X สูงสุดของรายการที่ไม่ซ้ำกัน) เมื่อคุณจัดเรียงไฟล์โดยใช้ "sort" แล้วคุณสามารถใช้ แอพเล็ก ๆ น้อย ๆ ที่ฉันสร้างขึ้นที่นี่:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java


2
ดีสำหรับคุณ! แต่ในกรณีของคุณคุณสามารถใช้cat unsorted-file | sort | uniq | head -X- Xจำนวนแถวแรกที่คุณต้องการส่งออกได้เมื่อใด
Slavik Meltser

@SlavikMe ขอบคุณมากสำหรับความคิดเห็น! อย่างไรก็ตามคำแนะนำของคุณให้ผลลัพธ์ที่แตกต่างออกไป .. คำแนะนำของคุณได้รับ X บรรทัดแรกในไฟล์ที่จัดเรียงทั้งหมดในขณะที่เราต้องการรับ X บรรทัดแรกต่อ "คีย์" (เช่นหากคุณมี CSV ที่มีชื่อถ้าคุณจัดเรียง ตามคอลัมน์ 2 "นามสกุล" จากนั้นคำสั่งของคุณอาจได้รับเพียง 3 บรรทัดโดยมี "Allen" เป็นนามสกุลในขณะที่ของเราจะได้รับ "Allen", "Brittain", "Charles" เป็นต้น) ขอบคุณมาก!
Daniel Iversen

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