Linux
對多個文件進行排序並合併
我想以相反的順序對幾個文本文件進行排序,然後合併/cat 到一個文本文件。
a.txt
0 33.1 2 33.0 10 21.1 20 21.8
b.txt
0 30.1 2 33.0 10 28.1 20 27.8
等等
*.txt
文件我想要這樣的輸出
20 21.8 10 21.1 2 33.0 0 33.1 20 27.8 10 28.1 2 33.0 0 30.1
我不想這樣
20 21.8 20 27.8 10 21.1 10 28.1 2 33.0 2 33.0 0 33.1 0 30.1
我試過這些程式碼
for file in *.txt ; do sort -nrk 1,1 *.txt > "$file" ; done
我也試過
sort -m *.txt
但是這些程式碼的輸出不是我想要的。
我正在尋找使用
sort
merge
paste
cat
或其他相關選項的解決方案。非常感謝您的幫助。
分別對文件進行排序,並將整個輸出重定向到結果文件:
for file in *.txt ; do sort -k1,1rn < "$file" done > file.concatenated
(這裡重要的是輸出文件沒有
.txt
副檔名,因為它是由重定向首先創建的)。或者,如果您想對文件進行適當的排序(重寫它們自己排序):
set -- *.txt ok=true for file do sort -o "$file" -k1,1rn -- "$file" || ok=false done "$ok" && cat -- "$@" > file.concatenated
這種兩階段方法允許我們在創建連接文件之前檢測文件排序中的問題。
您的第一個循環不起作用,因為您
.txt
在每次循環中都傳遞了完整的文件列表。
sort -m
是將已經排序的文件合併到排序的輸出中。這與你想要的相反。您想要對尚未排序的文件進行排序,並且只是連接結果而不將它們合併到排序的輸出中。在這裡,文件似乎按正序排序。如果您可以依靠始終如一的情況,那麼您應該能夠將它們反轉,這比反向排序它們更有效。
要做到這一點,GNU 系統有一個
tac
命令,還有幾個其他的tail -r
(雖然要注意一些實現只接受一個文件參數,所以你可能需要使用那些循環)。tac -- *.txt > file.concatenated
另請注意,這
-k1,1rn
與-rnk1,1
解決關係不同。當兩行相等比較時,sort
訴諸於整行的詞法比較(例如這裡,1 a
與,1 b
相等比較-k1,1n
,但1 a
在1 b
詞法上出現在前面)。使用該
-r
選項,最後的比較是反向進行的。r
當將標誌添加到關鍵規範之一時,這不適用。GNU
sort
必須-s
禁用最後的比較,這將導致它保留相等比較的行的原始順序。