Сохранить имя последнего файла, который соответствует шаблону, к переменной в bash - PullRequest
0 голосов
/ 07 сентября 2018

Я отказываюсь анализировать ls вывод, потому что он нестабилен.

Первая попытка не удалась с read и find:

read VARIABLE < $(find ./ -type f -name "PATTERN" | sort -r)

Но это приводит к неоднозначному перенаправлению.

Вторая попытка не удалась: она сохранила файл /boot, не знаю почему, я не был в /:

find ./ -type f -name "PATTERN" | sort -r | read VARIABLE

Третья попытка не удалась: используйте subshell :

{ read VARIABLE; } < $(find ./ -type f -name "PATTERN" | sort -r)

Без изменений.

Наконец-то я добился того, чего хотел:

variable=$(find ./ -type f | sort -r | head -1)

Но решение меня не удовлетворяет, потому что использование head для извлечения первой строки кажется уродливым.
Кроме того, весьма вероятно, что мне понадобится только вторая строка (что я получу к head -2 | tail -1, я знаю)

Интересно, можно ли использовать какой-то вариант этого:

{ read line1 ; read line2; } < $(find ./ -type f -name "PATTERN" | sort -r)

1 Ответ

0 голосов
/ 07 сентября 2018

Синтаксис для Замена процесса определен неправильно, это <() и , а не <$(). Вы должны понимать, что <() помещает вывод команды во временный файл под /var/tmp или файловый дескриптор /dev/fd/* в зависимости от вашей ОС. Для работы с файлом с помощью команды read необходимо перенаправить его содержимое с помощью начального <, который помещает содержимое файла в стандартный поток ввода команды read для чтения строки.

read -r lastfile < <(find ./ -type f -name "PATTERN" | sort -r)

Помните, что подстановка процессов является функцией оболочки Bourne Again и недоступна в POSIX-совместимой оболочке Bourne sh.

Что касается других попыток, то тот, у которого есть труба, никогда не сработает

find ./ -type f -name "PATTERN" | sort -r | read VARIABLE

потому что VARIABLE устанавливается в под-оболочке из конвейера и никогда не будет передан в родительскую оболочку. Если бы вы напечатали его как и когда вы читаете его в дочерней оболочке, это сработало бы.

find ./ -type f -name "PATTERN" | sort -r | { read -r lastfile; echo "$lastfile" ; }

И у одного с составными операторами, включающими фигурные скобки { ;}, есть та же проблема использования неправильного синтаксиса для подстановки процесса, который должен был быть

{ read -r lastfile; } < <(find ./ -type f -name "PATTERN" | sort -r)

и тот, что с двумя read командами

{ read -r file1 ; read -r file2; } < <(find ./ -type f -name "PATTERN" | sort -r)
...