Обработка файлов с пробелами в именах

У меня есть много файлов, которые мне нужно просеять, особенно grep для определенных ключевых слов в файле, а не FILENAME. У меня есть более 300 файлов в файловой системе (поэтому файлы находятся в нескольких разных каталогах), а некоторые имеют пробелы в именах.

когда я ищу подачу с помощью find

find -type f 

и распечатать результаты, некоторые имена файлов идут по разным строкам, КОТОРЫЕ НЕ ХОРОШО.

Как я могу обращаться

Некоторые реализации команды grep такие как GNU grep могут самостоятельно переписывать каталоги. Если вы ищете строку «blahblah», вы можете сделать это:

 $ grep -r "blahblah" . 

Это будет grep через все файлы и каталоги, рекурсивно начинающиеся с текущего каталога . (будьте осторожны, что некоторые реализации, такие как старые версии GNU grep , также будут следовать символическим ссылкам при смене дерева каталогов). Это покажет вам имена файлов и результат, соответствующий шаблону поиска, по одному на строку. Если вы просто хотите, чтобы имена файлов без соответствующего содержимого добавляли ключ -l в grep .

 $ grep -rl "blahblah" . 

Если вы действительно хотите использовать find вы можете использовать способность find для выполнения команд в отношении файлов, которые он находит, используя переключатель -exec .

 $ find . -type f -exec grep "blahblah" {} + 

Символ + в конце является ключевым, так как он будет определять оптимальное количество имен файлов, которые find локали, и вызывать grep загружая в командной строке столько, сколько будет соответствовать. Эти имена файлов будут размещены там, где находятся фигурные скобки, {} . Легче визуализировать то, что он делает, если мы заменим команду echo в месте grep , вы, надеюсь, поймете, что я имею в виду.

пример

Скажем, у меня были следующие данные образца.

 $ mkdir -p dir{1..3} $ touch file{1..3} $ touch dir{1..3}/file{A..C} 

Теперь, когда я запускаю приведенную выше команду find используя echo поскольку наш grep стоит в:

 $ find . -type f -exec echo {} + ./file2 ./file1 ./dir2/fileA ./dir2/fileB ./dir2/fileC ./dir3/fileA ./dir3/fileB ./dir3/fileC ./file3 ./dir1/fileA ./dir1/fileB ./dir1/fileC 

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

Используя вышеприведенный -type f -type, мы выполняем поиск только в обычных файлах, в то время как grep обычно будет выглядеть в каждом файле, таком как fifos, сокеты, устройства (но не обязательно символические ссылки) … Вы можете передать опцию -D skip для некоторых версий grep чтобы избежать поиска в устройствах / гнездах / fifos.

 find . -type f -print0 | xargs -0 grep yourstring 

Опция -print0 для поиска, а также ее -0 подвеска для xargs использует нуль-байты в качестве разделителя, что означает, что ваши имена файлов могут быть любыми, что вам нравится, и сюрпризов не будет.

Фактическая проблема заключается в том, что внутренний разделитель файлов оболочки (хранится в переменной IFS) является пространством. Вы можете изменить его как новую строку или что угодно, но реальное решение – использовать то, что я показал выше.