Как найти файлы в subdirs и отсортировать их по имени файла в единственной команде?

Друг работал :() { :|:&}; : на удаленном сервере, где у нас не было консольного доступа к. Не мог перезагрузить его, полностью замороженный, рабочий сервер.

Сломанный (запросом) для создания этого более читаемым.

:() # Define ':' as a function. Every time we say ':' execute the following code block
{ # Start of code block
    : # Call ':' again. 
    | # Pipe output to...
    : # Another ':' 
    & # Disown process. 
    # All on one line this would read :|:&, 
} # End of code block
; # End definition of ':' as a function
: # Call ':'

Могло бы быть легче посмотреть на него как

bomb() { bomb|bomb& }; bomb
9
23.05.2011, 11:43
3 ответа

Необходимо отсортировать по последнему полю (рассмотрение / как разделитель полей). К сожалению, я не могу думать об инструменте, который может сделать это, когда количество полей варьируется (если только sort -k мог принять отрицательные значения).

Для обхождения этого необходимо будет сделать decorate-sort-undecorate. Таким образом, возьмите имя файла и поместите его вначале сопровождаемый разделителем полей, затем сделайте вид, затем удалите первый столбец и разделителя полей.

find . ! -path "./build*" -name "*.txt" |\
    awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
    sort -n -t / |\
    cut -f2- -d/

Это awk команда говорит разделителя полей FS установлен на /; это влияет на способ, которым это читает поля. Выходной разделитель полей OFS также установлен на /; это влияет на способ, которым это печатает записи. В следующем заявлении говорится, печатают последний столбец (NF количество полей в записи, таким образом, это также, оказывается, индекс последнего поля), а также целая запись ($0 целая запись); это распечатает их с OFS между ними. Затем список sortредактор, рассматривая / как разделитель полей - так как у нас есть имя файла сначала в записи, оно отсортирует по этому. Затем cut печать только поля 2 через конец, снова рассматривая / как разделитель полей.

9
27.01.2020, 20:06
  • 1
    Так как это с находкой (1), можно пропустить awk часть и использование -printf '%f/%p\n' –  camh 23.05.2011, 06:20
  • 2
    действительно наша установка немного более сложен. Это действительно включает переменную subdir глубины. Отредактированный вопрос отразить этот факт. Мои извинения за не включая это сначала. –  unode 23.05.2011, 11:44
  • 3
    @Unode: решение Shawn обрабатывает переменную глубину очень хорошо, это - каноническое решение этой проблемы (до незначительных изменений). –  Gilles 'SO- stop being evil' 23.05.2011, 12:40

В zsh ≥4.3.10:

print -l -- **/*.txt~build*(oe\''REPLY=${REPLY:t}'\')
  • **/*.txt соответствия *.txt в текущем каталоге и его подкаталогах рекурсивно.
  • ~build* исключает соответствия, текст которых начинается build* (как ! -path './build*'). (Вам нужно setopt extended_glob сначала.)
  • (oe\''…'\') спецификатор шарика сортировки. REPLY=… создает строку к виду от строки для возврата.
  • ${REPLY:t} базовое имя (“хвост”) пути.
3
27.01.2020, 20:06
  • 1
    большое связанное волшебство. Интересный, но мы ограничены sh синтаксисом. +1 –  unode 23.05.2011, 11:37

Я использовал бы файлы '-printf' для вывода имени и пути, вид по имени и сокращение имя на последнем шаге. '###' является просто маркером, для помощи вырезанию.

find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'

%f печатает имя файла, %p целый путь.

Я упростил находить-команду для получения его в одну строку, конечно, Вы уедете ! -path "./build*" часть.

3
27.01.2020, 20:06

Теги

Похожие вопросы