Bash

如何對多個文件名部分的文件進行排序?

  • July 2, 2019

我有格式的文件名STR_NUM1_STR_NUM2_NUM3_NUM4_STR.datNUM1對許多文件重複。我想首先基於NUM1每個 NUM1 組對文件進行排序,我希望文件基於NUM4. 我怎樣才能在 bash 中做到這一點?

Tmp1_24298_Data_545_547_63359_Sample.dat
Tmp1_24298_Data_667_669_63637_Sample.dat
Tmp1_24298_Data_683_685_63517_Sample.dat
Tmp1_24298_Data_695_697_63557_Sample.dat
Tmp1_24298_Data_701_703_63437_Sample.dat
Tmp1_28703_Data_545_547_63833_Sample.dat
Tmp1_28703_Data_667_669_64111_Sample.dat
Tmp2_28703_Data_683_685_63951_Sample.dat
Tmp2_28703_Data_695_697_64031_Sample.dat
Tmp2_28703_Data_701_703_63910_Sample.dat
Tmp2_28707_Data_545_547_64306_Sample.dat
Tmp2_28707_Data_667_669_64545_Sample.dat
Tmp2_28707_Data_683_685_64424_Sample.dat
Tmp2_28707_Data_295_697_64505_Sample.dat
Tmp2_28707_Data_701_703_64344_Sample.dat

總而言之,_作為欄位分隔符,您希望對第二個和第六個欄位中的數字進行排序。在這種情況下,如果文件名位於名為 的文件中filenames,每行一個文件,則使用:

$ sort -nt_ -k2,2 -k6,6 filenames
Tmp1_24298_Data_545_547_63359_Sample.dat
Tmp1_24298_Data_701_703_63437_Sample.dat
Tmp1_24298_Data_683_685_63517_Sample.dat
Tmp1_24298_Data_695_697_63557_Sample.dat
Tmp1_24298_Data_667_669_63637_Sample.dat
Tmp1_28703_Data_545_547_63833_Sample.dat
Tmp2_28703_Data_701_703_63910_Sample.dat
Tmp2_28703_Data_683_685_63951_Sample.dat
Tmp2_28703_Data_695_697_64031_Sample.dat
Tmp1_28703_Data_667_669_64111_Sample.dat
Tmp2_28707_Data_545_547_64306_Sample.dat
Tmp2_28707_Data_701_703_64344_Sample.dat
Tmp2_28707_Data_683_685_64424_Sample.dat
Tmp2_28707_Data_295_697_64505_Sample.dat
Tmp2_28707_Data_667_669_64545_Sample.dat

如果文件在目前目錄中,則 POSIX 解決方案是:

$ find . -maxdepth 1 -type f -name '*.dat' | sort -nt_ -k2,2 -k6,6
Tmp1_24298_Data_545_547_63359_Sample.dat
Tmp1_24298_Data_701_703_63437_Sample.dat
Tmp1_24298_Data_683_685_63517_Sample.dat
Tmp1_24298_Data_695_697_63557_Sample.dat
Tmp1_24298_Data_667_669_63637_Sample.dat
Tmp1_28703_Data_545_547_63833_Sample.dat
Tmp2_28703_Data_701_703_63910_Sample.dat
Tmp2_28703_Data_683_685_63951_Sample.dat
Tmp2_28703_Data_695_697_64031_Sample.dat
Tmp1_28703_Data_667_669_64111_Sample.dat
Tmp2_28707_Data_545_547_64306_Sample.dat
Tmp2_28707_Data_701_703_64344_Sample.dat
Tmp2_28707_Data_683_685_64424_Sample.dat
Tmp2_28707_Data_295_697_64505_Sample.dat
Tmp2_28707_Data_667_669_64545_Sample.dat

這個怎麼運作

  • -n告訴sort按數字排序。
  • -t_告訴sort用作_欄位分隔符。
  • -k2,2 -k6,6 告訴sort首先對第二個欄位進行排序,如果第二個欄位相等,則對第六個欄位進行排序。

GNU 解決方案(處理包含換行符的文件名)

要處理本身包含換行符的文件名,我們需要使用 NUL 分隔。這意味著使用-print0withfind-zwithsort然後,使輸出可列印以在此處顯示,使用以下命令將 NUL 轉換為換行符tr

$ find . -maxdepth 1 -type f -name '*.dat' -print0 | sort -znt_ -k2,2 -k6,6 | tr '\0' '\n'
./Tmp1_24298_Data_545_547_63359_Sample.dat
./Tmp1_24298_Data_701_703_63437_Sample.dat
./Tmp1_24298_Data_683_685_63517_Sample.dat
./Tmp1_24298_Data_695_697_63557_Sample.dat
./Tmp1_24298_Data_667_669_63637_Sample.dat
./Tmp1_28703_Data_545_547_63833_Sample.dat
./Tmp2_28703_Data_701_703_63910_Sample.dat
./Tmp2_28703_Data_683_685_63951_Sample.dat
./Tmp2_28703_Data_695_697_64031_Sample.dat
./Tmp1_28703_Data_667_669_64111_Sample.dat
./Tmp2_28707_Data_545_547_64306_Sample.dat
./Tmp2_28707_Data_701_703_64344_Sample.dat
./Tmp2_28707_Data_683_685_64424_Sample.dat
./Tmp2_28707_Data_295_697_64505_Sample.dat
./Tmp2_28707_Data_667_669_64545_Sample.dat

引用自:https://unix.stackexchange.com/questions/527964