2015-05-18 5 views
1

Мне нужно создать список аргументов для find, используя значения, известные только во время выполнения. Я пытаюсь использовать массив для этого.Строка списка аргументов с массивом

Ниже приведена упрощенная версия, в которой используются жестко закодированные значения. Когда я повторяю команду, она кажется правильной (и когда я запускаю ее вручную, она делает то, что я ожидаю). Когда он входит в цикл for, он работает find (потому что я вижу те же ошибки около Permission denied для каталогов, принадлежащих другим пользователям, как при запуске вручную). Но внутри цикла for он не выдает ни одного из файлов .txt, обнаруженных вручную.

Что я сделал не так?

#!/bin/bash 

args=(/tmp -iname \"*.txt\") 

#args+=(-o -iname \"*.jpg\") 

echo command will be: find ${args[@]} 
for f in $(find ${args[@]}); do 
    echo found $f 
done 

Принятый ниже ответ правильно идентифицировал проблему. Но если добавить дополнительный -iname пункт, мой сценарий «игнорирует» все, кроме последнего, как описано здесь:

#!/bin/bash 

args=($1) 
args+=(-maxdepth $2) 
args+=(-iname "*$3") 
args+=(-o -iname "*$4") 
echo command will be: find "${args[@]}" 

find "${args[@]}" -print 2>/dev/null | while read -r f; do 
    echo found "$f" 
done 

Например, при вызове с /home/me 2 .jpg .png это правильно повторяет, что команда будет find /home/me -maxdepth 2 -iname *.jpg -o -iname *.png, но только тогда мой сценарий перекликается с найденными .png файлами.

+1

Укажите свои переменные. (например, '' $ {args [@]} "', "$ f" и т. д.) Также не читайте вывод find, как это. http://mywiki.wooledge.org/DontReadLinesWithFor http://mywiki.wooledge.org/BashFAQ/001 –

+0

Не избегайте кавычек. – Barmar

ответ

3

Вы не должны избегать цитат. Это сделает их буквальными, поэтому он попытается найти файлы, имена которых на самом деле начинаются и заканчиваются двойными кавычками.

args=(/tmp -iname "*.txt") 

Тогда вам нужно поставить кавычки ${args[@]} сказать оболочке, что она должна Requote их при расширении массива:

find "(" "${args[@]}" ")" -print | while read -r f 
do 
    echo found "$f" 
done 
+0

Спасибо. Я столкнулся с другим вопросом и добавил его к вопросу вместо того, чтобы придерживаться его в этом комментарии, поскольку он позволяет лучше форматировать. – user1011471

+0

Когда вы используете '-o', вам нужно действие в каждой ветви. Я исправил ответ, чтобы поставить parenthese вокруг всего, чтобы сгруппировать их. – Barmar

+0

Hm. На самом деле parens вокруг всех args не работал для меня, но parens вокруг только '-iname' clauses. Но другой ответ, в котором упоминались такие parens, исчез ... – user1011471

1

Bash4 можно расширить с рекурсивно шарики shopt -s globstar.
Просто используйте array=(/tmp/**/*.txt), чтобы получить все элементы.

Смежные вопросы