Как отсортировать результаты поиска (включая вложенные каталоги) по алфавиту в bash
У меня есть список каталогов, основанный на результатах выполнения команды "найти" в bash. Как пример, результатом поиска являются файлы:
test/a/file
test/b/file
test/file
test/z/file
Я хочу отсортировать вывод, чтобы он выглядел так:
test/file
test/a/file
test/b/file
test/z/file
Есть ли способ отсортировать результаты в команде поиска или передать результаты в сортировку?
4 ответа
Если у вас есть версия find для GNU, попробуйте это:
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
команда, используемая для подсчета количества слешей, что эквивалентно "глубине" файла.
(Я очень надеюсь, что есть более простой ответ. То, что вы спрашиваете, не кажется таким уж сложным, но я отказываюсь от простого решения.)
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
(На основе ответа Джона Кугельмана с удаленным элементом «глубина», что является абсолютно избыточным.)
Если вы хотите сортировать по алфавиту, лучший способ это:
find test -print0 | sort -z
(Пример в оригинальном вопросе на самом деле хотел файлы перед каталогами, что не то же самое и требует дополнительных шагов)
Попробуй это. для справки, он производит сортировку на втором поле второго символа. который существует только в файле и имеет ar для обратного значения, то есть он первый, после этого он будет сортироваться по первому символу второго поля. [-t это разделитель полей, -k это ключ]
find test -name file |sort -t'/' -k2.2r -k2.1
сделать info sort
для получения дополнительной информации. Существует множество способов использовать -t и -k вместе, чтобы получить разные результаты.