![如何对多个文件名部分的文件进行排序?](https://linux22.com/image/156417/%E5%A6%82%E4%BD%95%E5%AF%B9%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%E5%90%8D%E9%83%A8%E5%88%86%E7%9A%84%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F%EF%BC%9F.png)
我的文件名格式为STR_NUM1_STR_NUM2_NUM3_NUM4_STR.dat
.NUM1
对许多文件重复。我想首先根据每个 NUM1 组对文件进行排序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
答案1
总而言之,_
作为字段分隔符,您希望对第二个和第六个字段中的数字进行排序。在这种情况下,如果文件名位于名为 的文件中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 分隔。这意味着使用-print0
withfind
和-z
with sort
and then,使输出可打印并在此处显示,使用以下命令将 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