2010-09-30 28 views
19

Tôi có tệp văn bản chứa ~ 300 nghìn hàng. Mỗi hàng có số lượng các trường được phân cách bằng dấu phẩy khác nhau, số cuối cùng được đảm bảo bằng số. Tôi muốn sắp xếp tệp theo trường số cuối cùng này. Tôi không thể làm:Bash: sắp xếp tệp văn bản theo giá trị trường cuối cùng

sort -t, -n -k 2 file.in > file.out 

vì số trường trong mỗi hàng không phải là hằng số. Tôi nghĩ rằng sed, awk có lẽ là câu trả lời, nhưng không chắc chắn như thế nào. Ví dụ:

awk -F, '{print $NF}' file.in 

cung cấp cho tôi giá trị cột cuối cùng, nhưng cách sử dụng giá trị này để sắp xếp tệp?

Trả lời

27

Sử dụng awk để đặt phím số lên phía trước. $NF là trường cuối cùng của bản ghi hiện tại. Sắp xếp. Sử dụng sed để loại bỏ khóa trùng lặp.

awk -F, '{ print $NF, $0 }' yourfile | sort -n -k1 | sed 's/^[0-9][0-9]* //' 
+6

không cần chuyển hướng. 'awk -F, '{print $ NF, $ 0}' yourfile' – ghostdog74

0

Có thể đảo ngược các trường của mỗi dòng trong tệp trước khi sắp xếp? Một cái gì đó như

perl -ne 'chomp; print(join(",",reverse(split(","))),"\n")' | 
    sort -t, -n -k1 | 
    perl -ne 'chomp; print(join(",",reverse(split(","))),"\n")' 

nên làm điều đó, miễn là dấu phẩy không bao giờ được trích dẫn theo bất kỳ cách nào. Nếu đây là tệp CSV chính thức (trong đó dấu phẩy có thể được trích dẫn bằng dấu gạch chéo ngược hoặc dấu cách) thì bạn cần một trình phân tích cú pháp CSV thực.

2
vim file.in -c '%sort n /.*,\zs/' -c 'saveas file.out' -c 'q' 
+1

Tại sao không sử dụng 'ex' nếu bạn đang đi để đi con đường đó? Vim nhận được chức năng cụ thể đó từ 'ex'. –

+0

'ex' chỉ là' vim', với tùy chọn '-e'. Không thực sự quan trọng trong trường hợp này. – Benoit

+0

'ex' đặt trước' vim' (và 'vi') trong một thời gian khá dài. 'vim' có thể có một chế độ mô phỏng' ex', nhưng điều này không làm cho nó 'ex'. –

0

Perl one-liner:

@lines=<STDIN>;foreach(sort{($a=~/.*,(\d+)/)[0]<=>($b=~/.*,(\d+)/)[0]}@lines){print;} 
0

Tôi sẽ ném tôi ở đây như một sự thay thế (và tôi không thể có được awk để làm việc) :)

tập tin mẫu :

Call of Doody       1322 
Seam the Ripper       1329 
Mafia Bots 1       1109 
Chicken Fingers       1243 
Batup Light        1221 
Hunter F Tomcat       1140 
Tober         0833 

mã:

for i in `sed -e 's/.* \(\d\)*/\1/' file.txt | sort`; do grep $i file.txt; done > file_sort.txt 
0

Python one-liner:

python -c "print ''.join(sorted(open('filename'), key=lambda l: int(l.split(',')[-1])))" 
Các vấn đề liên quan