Как я могу обрабатывать пробелы в именах файлов при использовании xargs в результатах поиска?
Одна из моих общих практик - выполнять greps для всех файлов определенного типа, например, находить все файлы HTML, в которых есть слово "rumpus". Для этого я использую
find /path/to -name "*.html" | xargs grep -l "rumpus"
Время от времени, find
вернет файл с пробелом в имени, например my new file.html
, когда xargs
передал это grep
Однако я получаю эти ошибки:
grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory
Я вижу, что здесь происходит: или труба или xargs
обрабатывает пробелы в качестве разделителей между файлами. Впрочем, я не могу понять, как предотвратить такое поведение. Можно ли это сделать с find
+ xargs
? Или я должен использовать совершенно другую команду?
3 ответа
Использование
find ... -print0 | xargs -0 ...
например
find /path/to -name "*.html" -print0 | xargs -0 grep -l "rumpus"
со страницы поиска
-print0
True; print the full file name on the standard output, followed
by a null character (instead of the newline character that
‘-print’ uses). This allows file names that contain newlines or
other types of white space to be correctly interpreted by pro-
grams that process the find output. This option corresponds to
the ‘-0’ option of xargs.
Вам не нужно использовать xargs, потому что find может выполнять команды самостоятельно. При этом вам не нужно беспокоиться о интерпретации символов оболочки в имени.
find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +
со страницы поиска
-exec команда {} +
Этот вариант действия -exec запускает указанную команду для выбранных файлов, но командная строка создается путем добавления каждого выбранного имени файла в конце; общее количество вызовов команды будет намного меньше, чем количество совпавших файлов. Командная строка строится почти так же, как xargs создает свои командные строки. Только один экземпляр `{}'разрешен в команде. Команда выполняется в начальном каталоге.
Если версии find и xarg в вашей системе не поддерживаются -print0
а также -0
переключатели (например, AIX find и xargs) вы можете использовать это:
find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"
Здесь sed позаботится о том, чтобы избежать пространства для xargs.