如何在bash中按字母顺序对查找结果(包括嵌套目录)进行排序

时间:2013-01-23 23:01:41

标签: bash sorting find

我有一个基于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?

4 个答案:

答案 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 -ntest/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一起使用来获得不同的结果。