Заменить всю строку, содержащую строку с помощью Sed



у меня есть текстовый файл, который имеет определенную линию что-то вроде



sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext


мне нужно заменить всю строку с



This line is removed by the admin.


ключевое слово поиска TEXT_TO_BE_REPLACED



мне нужно написать shell-скрипт для этого. Как я могу достичь этого с помощью sed?

640   10  

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\ команда странная, и я не мог заставить ее работать
  • Я не понимал, что некоторые из моих проблем исходят из неоткрытых косых черт

Итак, вот решение, которое я придумал, которое, я думаю, должно работать в большинстве случаев:

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

Так что если вы установите шаблон "ревизия: 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
'

он работает

все ответы, представленные до сих пор, предполагают, что вы знаете что-то о заменяемом тексте, что имеет смысл, так как это то, что ОП спросил. Я предоставляю ответ, который предполагает, что вы ничего не знаете о заменяемом тексте и что в файле может быть отдельная строка с тем же или подобным содержимым, которое вы не хотите заменять. Кроме того, я предполагаю, что вы знаете номер строки должны быть заменены.

следующие примеры демонстрируют удаление или изменение текста по конкретным номерам строк:

# 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./'

Я очень часто использую регулярное выражение для извлечения данных из файлов, я просто использовал это, чтобы заменить буквальная цитата \" С // ничего :-)

cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed  s/\"//g  | cut -d, -f1 > list.txt

Comments

    Ничего не найдено.