Ниже приведена простая командная строка Bash:
grep -li 'regex' "filename with spaces" "filename"
Нет проблем. Также следующие работы прекрасно:
grep -li 'regex' $(<listOfFiles.txt)
где listOfFiles.txt
содержит список имен файлов, которые будут grepped, один
имя файла в строке.
Проблема возникает, когда listOfFiles.txt
содержит имена файлов с
встроенные пространства. Во всех случаях, которые я пробовал (см. Ниже), Bash разделяет
имена файлов в пространствах, поэтому, например, строка в listOfFiles.txt
содержащее имя типа ./this is a file.xml
, пытается запустить
grep на каждой части (./this
, is
, a
и file.xml
).
Я думал, что я довольно продвинутый пользователь Bash, но я не могу найти простое магическое заклинание, чтобы заставить это работать. Вот что я имею попробовал.
grep -li 'regex' `cat listOfFiles.txt`
Не работает, как описано выше (я действительно не ожидал, что это сработает), поэтому я подумал, что я бы поставил кавычки вокруг каждого имени файла:
grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`
Bash интерпретирует кавычки как часть имени файла и дает "Нет таких файла или каталога "для каждого файла (и все еще разделяет имена файлов с заготовки)
for i in $(<listOfFiles.txt); do grep -li 'regex' "$i"; done
Это не так, как для первоначальной попытки (т.е. ведет себя так, как будто кавычки игнорируются) и очень медленно, так как он должен запускать один 'grep' процесс на файл вместо обработки всех файлов в одном вызове.
Следующие работы, но требуют некоторого осторожного двойного экранирования, если регулярное выражение содержит метасимволы оболочки:
eval grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt`
Это единственный способ построить командную строку, чтобы она правильно обрабатывать имена файлов с пробелами?