Sed с множественным выражением для аргументации на месте

24

Я пытаюсь заменить несколько слов в файле с помощью sed -i #expression1 #expression2

файл

Something  123 item1
Something  456 item2
Something  768 item3
Something  353 item4

Выход (желаемый)

anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4

Попробуйте-аутов

Я могу получить следующий вывод, используя sed -iдля 2 раза.

 sed -i 's/Some/any/g' file
 sed -i 's/item/stuff/g' file

Могу ли я иметь любой возможный способ сделать это как одну команду на месте, как

sed -i 's/Some/any/g' -i 's/item/stuff/g' file

Когда я попробовал приведенный выше код, он принимает s/item/stuff/gкак файл и пытается работать над ним ..

JigarGandhi
источник
Если ваши файлы похожи на приведенный выше пример (т.е. они следуют одному и тому же шаблону), вы можете сделать это с помощью одной замены:sed - i 's/Some\(.*\)item/any\1stuff/' file
don_crissti

Ответы:

26

В зависимости от версии sedвашей системы вы можете сделать

sed -i 's/Some/any/; s/item/stuff/' file

Здесь вам не нужен gпосле косой черты в sкоманде, так как вы делаете только одну замену на строку.

В качестве альтернативы:

sed -i -e 's/Some/any/' -e 's/item/stuff/' file

-iОпция указывает sedредактировать файлы на месте; если сразу после этого есть символы, -iто sedрезервная копия исходного файла и использует эти символы в качестве расширения файла резервной копии. Например,

sed -i.bak 's/Some/any/; s/item/stuff/' file

или

sed -i'.bak' 's/Some/any/; s/item/stuff/' file

будет изменять file, сохраняя оригинал в file.bak.

Конечно, в Unix (или Unix-подобной) системе мы обычно используем «~» вместо «.bak», поэтому

sed -i~ 's/Some/any/;s/item/stuff/' file
PM 2Ring
источник
2
Обратите внимание, что вы описываете вариант GNU. Вариант BSD (как во FreeBSD или OS / X) требует аргумента для -i. Так sed -i '' 's/a/b/;s/c/d/' fileили sed -i .back 's/a/b/;s/c/d/'или sed -i.back 's/a/b/;s/c/d/'там. Другие sedреализации обычно не поддерживают -i.
Стефан Шазелас
Спасибо @ StéphaneChazelas за разъяснение этого. И я думаю, мне следовало бы более четко сказать, что в GNU sed между пробелом и расширением не должно быть пробела -i.
PM 2Ring
sed -i 's/$username = "root"/$username = "newuser"/; s/$password = "password"/$password = "passwd"/; s/$dbname="handicraftstore"/$dbname="handicraft"' Web/database.phpРезультаты sed: -e expression #1, char 141: unterminated 'команда`
Alhelal
@alhelal Извините, комментарии не подходят для того, чтобы задавать вопросы. Но в любом случае, ваша последняя sкоманда пропускает свой финал /.
PM 2Ring
@ PM2Ring, так как я не заметил, что я догадался, что это связано с вашим решением. Тем не менее, спасибо.
Алхелал
10

Вы можете связать выражения sed вместе с ";"

%sed -i 's/Some/any/g;s/item/stuff/g' file1
%cat file1
anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4
Ян МакГоуэн
источник
5

Несколько выражений с использованием нескольких -eпараметров:

sed -i.bk -e 's/Some/any/g' -e 's/item/stuff/g' file

или вы можете использовать только один:

sed -i.bk -e 's/Some/any/g;s/item/stuff/g' file

Вы должны указать расширение для файла резервной копии, так как при некоторой реализации sed, такой как OSX sed , не работает с пустым расширением (необходимо использовать sed -i ''для переопределения исходных файлов).

cuonglm
источник
1

Вы можете использовать Vim в режиме Ex:

ex -sc '%s/Some/any/|%s/item/stuff/|x' file
  1. % выбрать все строки

  2. s замена

  3. x сохранить и закрыть

Стивен Пенни
источник