我有一个包含文件列表的文本文件,例如:
file
A1/file
A1/B1/file
A2/file
如何对其进行排序,以便子目录中的文件列在父目录中的其他文件之前?
A1/B1/file
A1/file
A2/file
file
答案1
这里有一个简单的方法:
awk 'BEGIN{FS="/"; OFS="\t"}{print NF, $0}' file | sort -rn | cut -f2-
A1/B1/file
A2/file
A1/file
file
应该适用于简单的情况,比如你的问题。
如果您还想按目录排序:
awk 'BEGIN{FS="/"; OFS="\t"}{print NF, $0}' file | sort -k1,1rn -k2 | cut -f2-
A1/B1/file
A1/file
A2/file
file
答案2
zsh
具有rder glob 扩展epth-first 的od
glob 限定符,o
d
$ print -rC1 -- **/file(Nod)
A2/file
A1/B1/file
A1/file
file
如果使用限定符将文件列表加载到 glob 扩展中,则可以将其应用于任意文件列表e
。
$ print -rC1 -- /(Ne['reply=( ${(f)"$(<your-file)"} )']od)
A2/file
A1/B1/file
A1/file
file
还按名称排序on
:
$ print -rC1 -- /(Ne['reply=( ${(f)"$(<your-file)"} )']odon)
A1/B1/file
A1/file
A2/file
file
答案3
为了扩展@Kusalananda的见解,如果这些文件名确实是现有目录树的完整内容,find
则可以执行您想要的操作:
鉴于:
$ find .
./f2
./A1
./A1/B1
./A1/B1/f2
./A1/B1/f1
./A1/f2
./A1/f1
./A2
./A2/B1
./A2/B1/C1
./A2/B1/C1/f2
./A2/B1/C1/f1
./A2/f2
./A2/f1
./f1
GNUfind
可以:
$ find . -depth -type d -exec find {} -maxdepth 1 -not -type d \;
./A1/B1/f2
./A1/B1/f1
./A1/f2
./A1/f1
./A2/B1/C1/f2
./A2/B1/C1/f1
./A2/f2
./A2/f1
./f2
./f1
如果您关心目录中文件的排序,GNU find 会让您失望,因为它无法控制排序。你可能需要做类似的事情:
$ find . -depth -type d -exec sh -c 'find {} -maxdepth 1 -not -type d | sort' \;
./A1/B1/f1
./A1/B1/f2
./A1/f1
./A1/f2
./A2/B1/C1/f1
./A2/B1/C1/f2
./A2/f1
./A2/f2
./f1
./f2
FreeBSD 和 NetBSD 上的实用find
程序将识别-s
按文件名排序的标志:
$ find . -depth -type d -exec find -s {} -maxdepth 1 -not -type d \;
./A1/B1/f1
./A1/B1/f2
./A1/f1
./A1/f2
./A2/B1/C1/f1
./A2/B1/C1/f2
./A2/f1
./A2/f2
./f1
./f2
正如 @StéphaneChazelas 在评论中指出的那样,该-s
标志在 OpenBSD 中不可用。即使它可用,find -s
也可能会根据您的区域设置等而崩溃,如手册页所述:
注意:“find -s”和“find |” sort' 可能会给出不同的结果。