Заменить всю строку, содержащую строку, с помощью Sed
у меня есть текстовый файл, который имеет определенную линию что-то вроде
sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext
мне нужно заменить всю строку с
This line is removed by the admin.
ключевое слово поиска TEXT_TO_BE_REPLACED
мне нужно написать shell-скрипт для этого. Как я могу достичь этого, используя sed
?
10 ответов
можно использовать изменить команда для замены всей строки и -i
флаг для внесения изменений на месте. Например, с помощью GNU sed:
sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
вам нужно использовать wildards (.*
) до и после замены всей строки:
sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'
принятый ответ не работа для меня по нескольким причинам:
- моя версия sed не нравится
-i
С расширением нулевой длины - синтаксис
c\
команда странная, и я не мог заставить ее работать - Я не понимал, что некоторые из моих проблем исходят от unescaped slashes
Итак, вот решение, которое я придумал, которое, я думаю, должно работать для большинства случаев:
function escape_slashes {
sed 's/\//\\//g'
}
function change_line {
local OLD_LINE_PATTERN=; shift
local NEW_LINE=; shift
local FILE=
local NEW=$(echo "${NEW_LINE}" | escape_slashes)
sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
mv "${FILE}.bak" /tmp/
}
так использование образца чтобы исправить проблему:
change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile
ответ выше:
sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
отлично работает, если строка/строка замены не является переменной.
проблема в том, что на Redhat 5 \
после c
уходит $
. Двойной \
тоже не сработало (по крайней мере, на Redhat 5).
через хит и суд, я обнаружил, что \
после c
является избыточным, если строка/строка замены является только одной строкой. Поэтому я не использовал \
после c
, используется a переменная, как одна линия замены, и это была радость.
код будет выглядеть примерно так:
sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo
обратите внимание на использование двойных кавычек вместо одинарных кавычек.
в моем makefile я использую это:
@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md
PS:НЕ забудьте, что-i изменяет фактически текст в файле... поэтому, если шаблон, который вы определили как "ревизия", изменится, вы также измените шаблон для замены.
пример:
Abc-проект, написанный Джоном Доу
редакции: 1190
поэтому, если вы установите шаблон "Revision: 1190", это, очевидно, не то же самое, что вы определили их как "ревизию:" только...
bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90"
bash-4.1$
bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed
vim test4sed
'
'
'
DB_HOSTNAME=good replaced with 122.334.567.90
'
он работает
все ответы, представленные до сих пор, предполагают, что вы знаете что-то о заменяемом тексте, что имеет смысл, так как это то, что спросил OP. Я предоставляю ответ, который предполагает, что вы ничего не знаете о заменяемом тексте и что в файле может быть отдельная строка с тем же или подобным содержимым, которое вы не хотите заменять. Кроме того, я предполагаю, что вы знаете номер строки строки, которую нужно заменить.
следующие примеры демонстрируют удаление или изменение текста по определенным номерам строк:
# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
# just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE
# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file
done
файл find_replace содержит 2 столбца, c1 с шаблоном для соответствия, c2 с заменой, цикл sed заменяет каждую строку, содержащую один из шаблонов переменной 1
это похоже на выше одного..
sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'
Я очень часто использую regex для извлечения данных из файлов, которые я только что использовал, чтобы заменить буквальную цитату \"
С //
ничего :-)
cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed s/\"//g | cut -d, -f1 > list.txt