Intereting Posts

заменить на SED рекурсивно

Можно ли рекурсивно заменить образец в мульти-каталоге с помощью grep и sed?

grep -e "http://localhost:4000" -r ~/dev_web/_site | sed -e 's/http:\/\/localhost:4000/https:\/\/another_site.com/g' 

Когда я делаю это, мой терминал показывает мне, что сделано, но когда я делаю снова grep:

 grep -e "https://another_site.com" -r ~/dev_web/_site 

это показывает мне только 4 файла изменились ..

И если я сделаю:

  grep -e "http://localhost:4000" -r ~/dev_web/_site/ 

образец http: localhost: 4000 все еще здесь

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

Вместо этого, предполагая, что GNU sed :

 find ~/dev_web/_site -type f \ -exec grep -qF 'http://localhost:4000' {} ';' \ -exec sed -i 's#http://localhost:4000#https://another.site#g' {} + 

Это позволит найти все обычные файлы в каталоге или в каталоге ~/dev_web/_site . Для каждого такого файла grep сначала проверяет, содержит ли файл заданную строку. Если это так, GNU sed вызывается для замены на месте.

Шаг grep может быть опущен, но GNU sed обновит временную метку модификации для всех файлов без нее.

Возможно, вы захотите посмотреть только подмножество файлов в каталогах под ~/dev_web/_site . Если это так, ограничьте поиск с помощью -name '*.js' (или любого другого имени, которое вы хотите сопоставить) сразу после -type f .

Добавление -print непосредственно перед -exec sed ... приведет к выводу путей к файлам, которые find sed .

Связанные с:

  • Понимание опции -exec `find`

ваш сеанс sed работал с выводом grep, а не с файлом.

используйте grep для grep списка файлов (*)

 grep -e "http://localhost:4000" -r ~/dev_web/_site -l 

затем используйте xargs и sed -i для редактирования на месте

 xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g' 

(на боковой ноте вы можете изменить разделитель в седе)

Теперь все вместе

 grep -e "http://localhost:4000" -r ~/dev_web/_site -l | xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g' 

Конечно, это может быть одна линия, обратите внимание, что символ канала ( | ) можно использовать как продолжение строки.

(*) Я предполагаю, что в имени файла нет пробела, новой строки и другого забавного символа.

Ваш первый grep извлекает строки из файлов, а не список файлов.
Чтобы получить список подходящих файлов, используйте опцию -l для grep:

 $ grep -rl "htt...." ~/dir 

Чтобы выполнить модификацию файлов с помощью sed, задайте список для sed (инвертируйте порядок):

 $ sed -e 's#http://localhost:4000#https://another_site.com#g' \ $(grep -rle "http://localhost:4000" ~/dev_web/_site) 

Это предполагает “чистые” имена файлов: без пробелов и новых строк.

Более надежный вариант – использовать find:

 fromname='http://localhost:4000 toname='https://another_site.com' searchdir=~/dev_web/_site find "$searchdir" -type f \ -exec grep -qF "$fromname" {} ';' \ -exec sed -i 's#'"$fromname"'#'"$toname"'#g' {} +