grep -l выводит имена файлов с пробелами


4

Я хочу зациклить файлы с

for f in `grep -rsl "foo" . `: do sed -i -- "s/foo/bar/g" $f; done;

Но так как имена файлов содержат пробелы, имя файла разделяется при каждом обнаружении пробела.

Как я могу передать имя файла с пробелами в doблок?


Ответы:


4

Для работы со сложными именами файлов лучше всего разделять имена файлов символами NUL. GNU grepподдерживает это с помощью --nullопции и xargsподдерживает это с помощью -0опции. Таким образом, попробуйте:

grep --null -rslZ "foo" | xargs -0 sed -i -- "s/foo/bar/g"

Использование цикла оболочки

grep --null -rslZ "foo" | while IFS= read -r -d $'\0' file
    do 
        sed -i -- "s/foo/bar/g" "$file"
    done

Так нет способа заставить его работать for..in..do..done ?
doc_id

@slhck Спасибо. Я обновил ответ на вопрос, --nullкоторый поддерживается как GNU, так и FreeBSD . Страница людей OpenBSD , однако , не перечислить любую поддержку NUL.
John1024

@rahmanisback Нет. Вы можете смело забыть о forциклическом переборе имен файлов с пробелами.
lcd047

1
@rahmanisback Нет, это анти-паттерн. Когда вы имеете дело с файлами, это работает правильно только на расширениях глобуса, например for f in *.txt. Не пытайтесь делать что-то фантастическое там - это почти наверняка потерпит неудачу.
slhck

Для стандартных greps и т.п.:find . -type f -print0 | xargs -0 grep -sl 'foo' | tr '\n' '\0' | xargs -0 sed -i -e 's/foo/bar/g' --
lcd047

0

Вы можете смело забыть о for для зацикливания имен файлов с пробелами.

Не обязательно...

IFS=$'\n' && for NAV in `ps aux | egrep -o 'Google Chrome' | sort | uniq`; do
   open -a "$NAV" http://www.google.com
done
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.