Знайдіть і замініть sed у каталозі та підкаталогах


244

Я запускаю цю команду, щоб знайти та замінити всі події "apple" на "помаранчевий" у всіх файлах кореня мого сайту:

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
Звідки ви знаєте, що він не обробляє підкаталоги?
carlpett

тому що він дає ці помилки: sed: не вдалося відредагувати ./fpd: не звичайний файл sed: не вдалося відредагувати ./fpd/font: не звичайний файл sed: не вдалося редагувати ./fpd/font/makefont: не регулятор
hd.

ой ... я жартую за яблуком і нічого не знайшлося. їх усіх замінили. ;) спасибі . ти відкрив мені очі !!!
hd

Відповіді:


422

Ваш висновок повинен виглядати так, щоб уникнути надсилання імен каталогів на 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 / ... наRE error: illegal byte sequence
kakoma

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

84

Для більш великих завдань з 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 one
knocte

Без котирувань *.phpце дійсно неправильно; тобі просто пощастило, що він не розширився у стартовому каталозі, тому що у тебе там не було відповідних файлів.
tripleee

3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"

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

якщо "sed" не працює, спробуйте:

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

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