我有很多这样命名的文件:
n2+_PiU_w4_5348757.out
n2+_PiU_w2_5348755.out
n2+_PiU_w1_5348742.out
n2+_PiU_w1_5348729.out
n2+_PiU_w1_5348696.out
n2+_PiU_st3_w3_part6_5630814.out
n2+_PiU_st3_w3_part6_5630721.out
n2+_PiU_st3_w3_part5_5630720.out
n2+_PiU_st3_w3_part4_5630813.out
关键是,它们的名字可以完全不同,我需要按前面的数字.out
(即 ID)对它们进行排序。
我查看了一些类似的问题(根据第三列排序,Linux 对最后一列进行排序),但我无法使用sed
或awk
满足我的需要。
请您提供一些对它们进行排序的方法吗?最好使用bash
.
答案1
对于最近的 (> 4.0) GNU awk,使用以数字(倒数第二个)字段为键的关联数组:
printf '%s\0' * | gawk '
BEGIN {
RS="\000"; FS="[_.]";
PROCINFO["sorted_in"]="@ind_num_asc"
}
{
a[$(NF-1)]=$0
}
END {
for (k in a) print a[k]
}'
前任。
printf '%s\0' * | gawk 'BEGIN{RS="\000"; FS="[_.]"; PROCINFO["sorted_in"]="@ind_num_asc"} {a[$(NF-1)]=$0} END {for (k in a) print a[k]}'
n2+_PiU_w1_5348696.out
n2+_PiU_w1_5348729.out
n2+_PiU_w1_5348742.out
n2+_PiU_w2_5348755.out
n2+_PiU_w4_5348757.out
n2+_PiU_st3_w3_part5_5630720.out
n2+_PiU_st3_w3_part6_5630721.out
n2+_PiU_st3_w3_part4_5630813.out
n2+_PiU_st3_w3_part6_5630814.out
类似地,使用 perl 哈希:
printf '%s\0' * | perl -F'[_.]' -0ne '
$h{$F[$#F-1]} = $_ }{ for $k (sort { $a <=> $b } keys %h) {print "$h{$k}\n"}
'
答案2
与zsh
球:
$ printf '%s\n' *_<->.out(noe'(REPLY=${REPLY##*_})')
n2+_PiU_w1_5348696.out
n2+_PiU_w1_5348729.out
n2+_PiU_w1_5348742.out
n2+_PiU_w2_5348755.out
n2+_PiU_w4_5348757.out
n2+_PiU_st3_w3_part5_5630720.out
n2+_PiU_st3_w3_part6_5630721.out
n2+_PiU_st3_w3_part4_5630813.out
n2+_PiU_st3_w3_part6_5630814.out
<->
:任意数字序列(<x-y>
无限制)- (...): 全局限定符
n
: 数字顺序oe'(code)'
:根据以下评估进行排序code
:REPLY=${REPLY##*_}
:排序键是最后一个之后的部分_
答案3
awk
+sort
+cut
组合:
awk -F'_' '{ $0=$NF OFS $0 }1' files_list.txt | sort | cut -d' ' -f2-
-F'_'
- 字段分隔符$NF
- 最后一个字段(例如5348696.out
)$0=$NF OFS $0
- 在当前记录前面加上$0
最后一个字段$NF
值以进行进一步直接排序(例如5348757.out n2+_PiU_w4_5348757.out
)cut -d' ' -f2-
- 从第二个开始过滤字段
输出:
n2+_PiU_w1_5348696.out
n2+_PiU_w1_5348729.out
n2+_PiU_w1_5348742.out
n2+_PiU_w2_5348755.out
n2+_PiU_w4_5348757.out
n2+_PiU_st3_w3_part5_5630720.out
n2+_PiU_st3_w3_part6_5630721.out
n2+_PiU_st3_w3_part4_5630813.out
n2+_PiU_st3_w3_part6_5630814.out