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