Слишком многие из этих ответов используют расширение оболочки для хранения результатов поиска. Это не то, что вам нужно сделать легко.
Предположим, у меня 30 000 песен, а названия этих песен в среднем составляют около 30 символов. Допустим, мы даже не столкнемся с проблемой white space .
Моя находка вернет более 1 000 000 символов, и очень вероятно, что мой буфер командной строки не такой большой. Если бы я сделал что-то вроде этого:
for file in $(find -name "*.mp3")
do
echo "some sort of processing"
done
Проблема (помимо пробела в именах файлов) заключается в том, что ваш буфер командной строки просто отключит переполнение из find
. Это может даже сильно потерпеть неудачу.
Вот почему была создана команда xargs
. Он гарантирует, что буфер командной строки никогда не переполняется. Он будет выполнять команду, следующую за xargs
столько раз, сколько необходимо для защиты буфера командной строки:
$ find . -name "*.mp3" | xargs ...
Конечно, используя xargs
, этот способ все равно будет задыхаться на белом фоне, но современный реализации xargs
и find
имеют способ решить эту проблему:
$ find . -name "*.mp3 -print0 | xargs --null ...
Если вы можете гарантировать, что имена файлов не будут иметь вкладок или \n
(или двойных пробелов) в них , лучше всего найти поиск в цикле while:
find . -name "*.mp3" | while read file
do
Конвейер отправит файлы в while read
до заполнения буфера командной строки. Более того, read file
читается по всей строке и помещает все элементы, найденные в этой строке, в $file
. Это не идеально, потому что read
все еще ломается на пробел, поэтому имена файлов, такие как:
I will be in \n your heart in two lines.mp3
I love song names with multiple spaces.mp3
I \t have \t a \t thing \t for \t tabs.mp3.
По-прежнему будут работать. Переменная $file
увидит их как:
I will be in
your heart in two lines.mp3
I love song names with multiple spaces.mp3
I have a thing for tabs.mp3.
Чтобы обойти эту проблему , вы должны использовать find ... -print0
для использования нулей в качестве входных разделителей. Затем либо измените IFS
на использование нулей, либо используйте параметр -d\0
в инструкции while при чтении в оболочке BASH.