2010-01-18 3 views
35

Я пытаюсь использовать массив для хранения списка имен файлов с помощью команды find.Как обрабатывать результаты поиска в сценарии bash?

По какой-то причине массив не работает в bash, который используется в школе, но моя программа работает на моем собственном ноутбуке.

Так мне было интересно, если есть другой способ сделать это, это то, что у меня есть:

array = (`find . -name "*.txt"`) #this will store all the .txt files into the array 

Тогда я могу получить доступ к элементам массива и сделать копии всех файлов с помощью команды кошки.

Есть ли другой способ сделать это без использования массива?

ответ

75

Вы могли бы использовать что-то вроде этого:

find . -name '*.txt' | while read line; do 
    echo "Processing file '$line'" 
done 

Э.Г. сделать копию:

find . -name '*.txt' | while read line; do 
    echo "Copying '$line' to /tmp" 
    cp -- "$line" /tmp 
done 

НТН

+0

спасибо большое! он работал, и я узнал что-то новое. – Shellscriptbeginner

+0

Использование цикла 'for', безусловно, лучший выбор здесь. Использование массива будет работать, за исключением того, что он считывает весь список в переменную и затем выполняет итерацию по переменной. Эта версия читает каждое имя файла, поскольку оно исходит от 'find' и обрабатывает его в строке. –

+0

D.Shawley, не могли бы вы разместить образец с петлей? Думаю, он должен работать и с файлами с пробелами в названии. –

2
find . -name '*.txt' | while IFS= read -r FILE; do 
    echo "Copying $FILE.." 
    cp "$FILE" /destination 
done 
6

Просто не ставьте пробелы вокруг знака равенства:

ar=($(find . -name "*.txt")) 

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

В большинстве случаев вам будет лучше всего обслуживать, если вы выполните итерацию через результат поиска -exec, -execdir, -ok или -okdir.

Для петель и в то время как петли трудно сделать правильно, когда дело доходит до пробелов в именах файлов или новых символах и вкладках.

find ./ -name "*.txt" -exec grep {} ";" 

{} не нуждается в маскировке. Вы часто будете видеть сочетание найти/xargs, который запускает дополнительный процесс тоже:

find ./ -name "*.txt" | xargs grep {} ";" 
14

У меня была проблема с решением Иоганна Вайса, если я просто делал эхо он будет работать для полного списка файлов. Однако, если я попытался запустить ffmpeg на следующей строке, скрипт обработает только первый файл, с которым он столкнулся. Я предположил некоторые смешные дела IFS из-за трубы, но я не мог понять это, и вместо этого работал с петлей для перерыва:

for i in $(find . -name '*.mov'); 
do 
    echo "$i" 
done 
+1

Это не удаляет пробелы в именах файлов – spinup

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