我在名为 files.txt 的文本文件中有以下文件列表:
./themes/seven/images/list-item-rtl.png
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./xmlrpc.php
./MAINTAINERS.txt
./update.php
./README.txt
./COPYRIGHT.txt
./web.config
我想仅按文件名对它们进行排序(按最后一次出现正斜杠后的第一个字符排序)。所以上面的输出会像这样:
./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php
我该怎么做呢?
答案1
$ awk -F '/' '{ printf "%s/%s\n", $NF, $0 }' files.txt | sort | cut -d '/' -f 2-
./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php
这会将文件名副本添加到行的前面,后跟一个/
字符。文件名是通过最后一个/
分隔字段获得的。最后一个字段$NF
位于awk
.
命令的输出awk
已排序。此排序将使用/
添加到行前面的 -delimited 字段。 cut
然后用于删除添加的/
- 分隔字段。
只要路径名不包含文字换行符,这种方法就可以工作。
/
如果任何路径名以字符结尾(可能是目录的路径名),也可能会出现问题。这些将在排序列中产生一个空字符串。
也可以看看:施瓦茨变换
答案2
使用 GNU awk ( gawk
) 之一,我指定数组遍历:
awk -F'/' 'BEGIN {PROCINFO["sorted_in"] = "@ind_str_asc"}
{ a[$NF]=$0 }
END { for ( i in a ) { print a[i] } }' files.txt
在这种情况下:将数据加载到数组中,索引由最后一个分隔字段(即文件名)定义/
,元素是文件的行。然后遍历按索引值排序的数组进行打印步骤。
仅基本实用程序:
paste <(rev files.txt | cut -d'/' -f 1 | rev) files.txt | sort | cut -f2