Найти и заменить на sed в каталоге и подкаталогах


244

Я запускаю эту команду, чтобы найти и заменить все вхождения «apple» на «orange» во всех файлах в корне моего сайта:

find ./ -exec sed -i 's/apple/orange/g' {} \;

Но это не проходит через подкаталоги.

Что не так с этой командой?

Вот некоторые строки вывода find ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php

Не могли бы вы запустить find ./и опубликовать пример вывода? И каталог структуры, пожалуйста. редактировать: спасибо!
Джейкоб

Хм, твоя находка верна, у меня работает с подкаталогами.
Джейкоб

1
Откуда ты знаешь, что он не обрабатывает подкаталоги?
Карлпетт

потому что он выдает следующие ошибки: sed: невозможно редактировать ./fpd: нет обычного файла sed: невозможно редактировать ./fpd/font: нет обычного файла sed: невозможно редактировать ./fpd/font/makefont: не регламент
HD.

ох ... я собрал яблоко и ничего не нашел. все они были заменены. ;) Спасибо . ты открыл мне глаза !!!
HD

Ответы:


423

Ваша находка должна выглядеть так, чтобы избежать отправки имен каталогов в sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;

19
Вы , возможно , потребуется изменить , sed -i 's/apple/orange/g'чтобы sed -i '' 's/apple/orange/g'сделать эту работу.
paulmelnikow

7
-iпринимает аргумент: расширение, используемое для сохранения временного файла. В GNU sed, похоже, между пробелом -iи его аргументом нет пробела , но в BSD sed есть… поэтому BSD -i '' 's/foo/bar/'эквивалентен GNU -i 's/foo/bar/.
paulmelnikow

20
На самом деле добавление -eне работает на Mac OS. touch a b c d eзатем выше команда выдает список каталогов , как это: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow

6
Для Mac OS это отвечает stackoverflow.com/questions/19242275/… theRE error: illegal byte sequence
kakoma

3
Для пользователей рыбных раковин обязательно указывайте пустые скобки '{}', потому что рыба автоматически расширяет пустые скобки, если не заключена в кавычки.
Кевин Черепский

86

Для больших задач s & r лучше и быстрее использовать grep и xargs, например;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'

20
Спасибо за этот ответ, это было очень полезно! Если в git-репозитории это еще быстрее, используяgit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues

4

Это сработало для меня:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;

оригинальный вопрос не ограничивается файлами * .php, есть также .ini
knocte

Без кавычек *.phpдействительно неправильно; вам просто повезло, что он не раскрылся в начальном каталоге, потому что у вас там не было подходящих файлов.
Трипли


1

Так как есть пользователи MacOS, которые читают этот (как я), следующий код работал для меня (10.14)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @

Все остальные ответы с использованием -iи-e не работают на macOS.

Источник


0

Я думаю, что мы можем сделать это одной простой командой

for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done

Обратитесь к этой странице .


-6

В linuxOS:

sed -i 's/textSerch/textReplace/g' namefile

если "седь" не работает, попробуйте:

perl -i -pe 's/textSerch/textReplace/g' namefile

4
он хочет найти все файлы в подкаталогах, содержащие эту строку и заменить, а не только один файл
phuclv
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.