我有一个基于bash中运行“find”命令结果的目录列表。例如,find的结果是文件:
test/a/file
test/b/file
test/file
test/z/file
我想对输出进行排序,使其显示为:
test/file
test/a/file
test/b/file
test/z/file
有没有办法在find命令中对结果进行排序,或者将结果排序为sort?
答案 0 :(得分:15)
如果你有GNU版本的find,试试这个:
find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}'
要在循环中使用这些文件名,请执行
find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}' | while read file; do
# use $file
done
find命令为每个文件打印三件事:(1)其目录,(2)目录树中的深度,以及(3)其全名。通过在输出中包含深度,我们可以使用sort -n
对test/file
上方test/a/file
进行排序。最后,我们使用awk
删除前两列,因为它们仅用于排序。
使用\0
作为三个字段之间的分隔符,可以让我们处理文件名,其中包含空格和制表符(不幸的是,不是新行)。
$ find test -type f
test/b/file
test/a/file
test/file
test/z/file
$ find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F'\0' '{print $3}'
test/file
test/a/file
test/b/file
test/z/file
如果您无法修改find
命令,请尝试这个错综复杂的替换:
find test -type f | while read file; do
printf '%s\0%s\0%s\n' "${file%/*}" "$(tr -dc / <<< "$file")" "$file"
done | sort -t '\0' | awk -F'\0' '{print $3}'
它做同样的事情,使用${file%/*}
来获取文件的目录名,并使用tr
命令来计算斜杠数,这相当于一个文件& #39; s&#34;深度&#34;。
(我当然希望那里有一个更简单的答案。你所要求的并不是那么难,但我想要一个简单的解决方案。)
答案 1 :(得分:0)
如果要按字母顺序排序,最好的方法是:
find test -print0 | sort -z
(原始问题中的示例实际上需要在目录之前放置文件,这不一样,需要额外的步骤)
答案 2 :(得分:0)
find test -type f -printf '%h\0%p\n' | sort | awk -F'\0' '{print $2}'
例如,find
的结果是
test/a'\0'test/a/file
test'\0'test/file
test/z'\0'test/z/file
test/b'\0'test/b/text file.txt
test/b'\0'test/b/file
其中 '\0'
代表空字符。
这些复合字符串可以用一个简单的 sort
正确排序:
test'\0'test/file
test/a'\0'test/a/file
test/b'\0'test/b/file
test/b'\0'test/b/text file.txt
test/z'\0'test/z/file
最后的结果是
test/file
test/a/file
test/b/file
test/b/text file.txt
test/z/file
(基于 John Kugelman 的回答,删除了绝对多余的“深度”元素。)
答案 3 :(得分:-1)
试试这个。作为参考,它在第二个字段第二个字符上排序第一。它只存在于文件中,并且r具有反向意义,它是第一个,之后它将对第二个字段的第一个字符进行排序。 [-t是字段分隔符,-k是关键字]
find test -name file |sort -t'/' -k2.2r -k2.1
执行info sort
了解详情。有很多不同的方法可以将-t和-k一起使用来获得不同的结果。