find: ничего не делать, если файлы не указаны

Если у вас последняя основанная на GNU система (чья sort предоставляет аналогичную -V natural-version) sort) вы можете отсортировать, используя это, и прочитать результат в массиве:

while read -rd '' f; do 
  files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)

Затем вы сможете расширить массив в своей команде convert :

convert "${files[@]}" out.pdf
2
23.05.2016, 11:37
4 ответа

Как насчет того, чтобы сделать это:

paths=$(do_something to find filenames)
if [ "$paths" ]; then
    find "$paths" ...
fi

Это работает независимо от реализации find .

Обратите внимание, что поиск "$ paths" с более чем одним именем пути вызывает проблемы. Если имена путей не содержат пробелов, вы можете использовать: find $ paths , в противном случае рабочей альтернативой является эта функция:

dofind() {
    set -f
    set -- $(do_something to find filenames)
    if [ $# -gt 0 ]; then
        find "$@" ...
    fi
    set +f
}

Она отключает подстановку файлов, а затем использует set - для установки вектора аргументов оболочки. Это работает с любой оболочкой POSIX.

3
27.01.2020, 21:52

В zsh (и в большинстве оболочек, не производных от Борна), когда a (или все в зависимости от shell) glob не расширяется, команда прерывается.

$ (do_something, чтобы найти имена файлов) не является глобусом, но вы можете сделать его им, добавив квалификатор glob в zsh :

 find $(do_something to find filenames)(#q) -print0...

Выше, что (# q) (пустой квалификатор glob, иначе ничего не делает) добавляется к последнему слову в результате разделения вывода do_something для поиска имен файлов , поэтому команда будет прервана, если эта команда не выводит (или не выводит пустой), но также, если это последнее слово (и только это последнее слово) не соответствует существующему пути. Вы можете применить его к каждому слову, полученному в результате этого разделения (чтобы команда была прервана, если какое-либо из этих слов не разрешается в существующий файл) с помощью:

 find ${^$(do_something to find filenames)}(#q) -print0...
0
27.01.2020, 21:52

С zsh я бы сделал:

files=($(do_something to find filenames))
(($#files)) && find $files ...

С tcsh :

set files=(`do_something to find filenames`)
if ($#files) find $files:q ...

С ] bash , mksh или ksh93 ,

set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...

POSIXly:

set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...

(в bash и других оболочках POSIX, $ (...) разбивает (на $ IFS : пробел, табуляция и новая строка по умолчанию), но также выполняет подстановку в результирующие слова, которые, я не ожидаю, вы здесь захотите, поэтому set -f . Другие оболочки ((t) csh, zsh, fish, rc, es ...) не имеют этой проблемы).

4
27.01.2020, 21:52

Вы можете дать find дополнительный, несуществующий каталог для начала работы:

find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld

Чтобы сделать это аккуратным, отбросьте вывод ошибок find:

find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld

(но тогда вы не заметите, если возникнет другая ошибка...).

Когда do_something to find filenames выводит имена файлов, find будет жаловаться на " ", но будет обрабатывать остальную часть командной строки. Когда имена файлов не выводятся, find снова пожалуется на " ", но не добавит свой стандартный .

0
27.01.2020, 21:52

Теги

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