Результат обычной находки с использованием 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
и когда сортируется с sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
Однако желаемый результат:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
Это означает, что выходные данные сортируются на основе только имени файла , но информация о папке должна сохраняться как часть выходных данных.
Изменить : сделать пример более сложным, так как структура подкаталога может включать более одного уровня.
-printf
вместоawk
), я думаю, что это лучшее решение. Я переработал мою первоначальную реализацию, чтобы использовать этот метод.Ответы:
Вам нужно отсортировать по последнему полю (рассматривая
/
как разделитель полей). К сожалению, я не могу вспомнить инструмент, который может сделать это, когда количество полей меняется (если бы толькоsort -k
могло принимать отрицательные значения).Чтобы обойти это, вам нужно сделать декорацию-сортировку-декорацию. То есть, взять имя файла и поместить его в начале, после которого следует разделитель полей, затем выполнить сортировку, а затем удалить первый столбец и разделитель полей.
Эта
awk
команда говорит, что разделитель полейFS
установлен в/
; это влияет на способ чтения полей. Сепаратор поля выводаOFS
также имеет значение/
; это влияет на способ печати записей. Следующий оператор говорит: напечатать последний столбец (NF
это число полей в записи, поэтому он также является индексом последнего поля), а также всю запись ($0
это вся запись); он напечатает их с OFS между ними. Затем списокsort
редактируется, рассматривая его/
как разделитель полей - так как у нас есть имя файла первым в записи, оно будет отсортировано по этому. Затемcut
печатает только поля 2 до конца, снова обрабатывая/
как разделитель полей.источник
-printf '%f/%p\n'
Я бы использовал файлы '-printf' для вывода имени и пути, сортировки по имени и обрезания имени на последнем шаге. «###» - это просто маркер, помогающий резать.
% f печатает имя файла,% p весь путь.
Я упростил команду find, чтобы вывести ее в одну строку, конечно, вы бы оставили
! -path "./build*"
часть.источник
В зш ≥4.3.10:
**/*.txt
совпадения*.txt
в текущем каталоге и его подкаталогах рекурсивно .~build*
исключает совпадения, текст которых начинается сbuild*
(как! -path './build*'
). (setopt extended_glob
Сначала нужно .)(oe\''…'\')
является классификатором глобуса сортировки .REPLY=…
создает строку для сортировки из строки для возврата.${REPLY:t}
это базовое имя («хвост») пути.источник