Найти и заменить на 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
HD.
источник
Не могли бы вы запустить 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' {} \;
jfg956
источник
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 {} \;
blackdad
источник
оригинальный вопрос не ограничивается файлами * .php, есть также .ini
knocte
Без кавычек *.phpдействительно неправильно; вам просто повезло, что он не раскрылся в начальном каталоге, потому что у вас там не было подходящих файлов.
Трипли
3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"
rocLv
источник
1

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

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

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

Источник

Pat-s
источник
0

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

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

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

Sukrant
источник
-6

В linuxOS:

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

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

perl -i -pe 's/textSerch/textReplace/g' namefile
ฉัตร ชัย สิทธิ วง ค์
источник
4
он хочет найти все файлы в подкаталогах, содержащие эту строку и заменить, а не только один файл
phuclv