使用正常查找的结果find . ! -path "./build*" -name "*.txt"
:
./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt
当排序时sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
然而期望的输出是:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
这意味着输出是根据仅文件名,但文件夹信息应作为输出的一部分进行维护。
编辑:使示例更加复杂,因为子目录结构可能包含多个级别。
答案1
您需要按最后一个字段排序(考虑/
作为字段分隔符)。不幸的是,我想不出一个工具可以在字段数量变化时执行此操作(如果只能sort -k
取负值)。
为了解决这个问题,你必须进行装饰-排序-取消装饰。也就是说,获取文件名并将其放在开头,后跟字段分隔符,然后进行排序,然后删除第一列和字段分隔符。
find . ! -path "./build*" -name "*.txt" |\
awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
sort -n -t / |\
cut -f2- -d/
该awk
命令表示字段分隔符 FS
被设定为/
;这会影响它读取字段的方式。这输出字段分隔符 OFS
也设置为/
;这会影响打印记录的方式。下一条语句说打印最后一列(NF
是记录中的字段数,因此它也恰好是最后一个字段的索引)以及整个记录($0
是整个记录);它将打印它们,并在它们之间添加 OFS。然后列表被sort
编辑,被/
视为字段分隔符 - 因为我们在记录中首先有文件名,所以它将按此排序。然后cut
仅打印字段 2 到末尾,再次将其/
视为字段分隔符。
答案2
我将使用文件“-printf”输出名称和路径,按名称排序,并在最后一步中截断名称。 “###”只是一个标记,帮助切割。
find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'
%f 打印文件名,%p 打印整个路径。
我简化了 find-命令,使其成为一行,当然你会留下这一! -path "./build*"
部分。