Использовать sed, как заменить шаблон, если он встречается в строке, следующей за другим шаблоном?

Скажем, следующее является содержимым файла

$ cat file Name=Tom Value=10 Name=Tom Name=Harry Value=20 

В некоторых случаях значение не возникает после имени. Поэтому мне нужно найти шаблон Name = Tom и заменить значение, но только если оно встречается в строке сразу после имени. Как это сделать?

  • Использовать sed для исправления сломанных строк новой строки
  • Как работать с несколькими командами sed в aix?
  • Как анализировать поля из текстового файла и записывать их в другой файл
  • Как написать сценарий sed для удаления чисел из строки?
  • Почему sed меняет разрешения файла на cifs, установленном share?
  • Как заменить строку в файле другим файлом?
  • Вывести только определенные поля
  • Удалить строку между двумя разными разделителями
  • 3 Solutions collect form web for “Использовать sed, как заменить шаблон, если он встречается в строке, следующей за другим шаблоном?”

    Более компактный и несколько более простой:

     sed 'G;/^Value=/s/=.*\nName=Tom/=42/;s/\n.*//;h' file 

    Это добавляет предыдущую строку из пространства удержания в каждую строку. Для строк Value= значение заменяется, если Name=Tom находился в удержании. В противном случае добавленная строка будет удалена, и строка будет сохранена в удержании для следующего цикла.

    с awk :

     awk 'prev ~ /^Name=(Tom|Anything)$/ && /^Value=/ {$0 = "Value=123"} {print; prev = $0}' 

    Или с именем и новым значением, хранящимся в переменной:

     export NAME=Tom VALUE=123 awk 'prev == "Name=" ENVIRON["NAME"] && /^Value=/ { $0 = "Value=" ENVIRON["VALUE"] } {print; prev = $0}' 

    С sed эквивалент будет примерно таким:

     sed -e 'x;/^Name=Tom$/{g;/^Value/s/=.*/=123/;h;b' -e '}' -eg 

    Хотя, как обычно, он короче, но значительно менее разборчив, чем с awk . Кроме того, для работы с произвольными значениями, хранящимися в переменных, sed не имеет эквивалента ENVIRON awk или возможности простого сравнения строк (в отличие от сопоставления регулярных выражений), поэтому вам нужно предварительно обработать значения переменных сначала, если вы не можете гарантировать, что переменные не содержат символов, специальных для sed .

     sed -e "x;/^Name=$NAME\$/{g;/^Value/s/=.*/=$VALUE/;h;b" -e '}' -eg 

    Было бы уязвимостью ввода команд (по крайней мере, с GNU sed ), если $NAME и $VALUE не будут жестко контролироваться.

     sed -e ' /^Name=Tom$/!b $!N /\(\nValue\)=.*/s//\1=NEW_VALUE/ P;D ' data.inp 

    объяснение

    • Он будет искать строки с именем Tom в них. Неправильное совпадение будет передано в стандартный вывод.
    • Затем он попытается добавить следующую строку в пространство шаблонов, если это не последняя строка.
    • Будем искать значение регулярного выражения = в только что добавленной строке, и если да, то значение изменяется на NEW_VALUE (вы должны изменить его на все, что вам нужно).
    • P; D => будет печатать часть пространства шаблонов слева от \ n, т. Е. Te prev line, которая имела Name = Tom, а затем удаляет эту часть. Теперь мы остаемся со значением = NEW_VALUE и с этим перескакиваем в начало строки сценария sed: / ^ Name = Tom $ /! B Очевидно, что это произойдет, и, следовательно, оно будет перенесено на стандартный вывод. Это делается для ухода за последовательными линиями Name = Tom.

    Результаты

     Name=Tom Value=NEW_VALUE Name=Tom Name=Harry Value=20 
    Interesting Posts

    Как сохранить разделитель полей при печати $ 0 с awk

    Chkrootkit обнаружил много подозрительных файлов и каталогов, и / sbin / init INFECTED

    Есть ли способ просмотра вывода консоли вместо загрузочного логотипа, в то время как моя машина RHEL 6.2 загружается?

    Можете ли вы установить программу для открытия «всегда сверху» по умолчанию в XFCE4 (xfwm4)?

    Логфайлы для не заканчивающихся процессов

    Добавление настраиваемой опции в настройках kde

    Сохранение видеоизображений движения на USB-накопителе

    OpenVPN генерирует тонну трафика

    MySQL и PHP (и другие языки)

    Сохраняйте раскладку клавиатуры при вставке внешней клавиатуры

    Почему интерфейс Linux Tun не возвращает ответы ICMPv6 Echo?

    тире: как захватить вывод ловушки (вызванные без аргументов)?

    Как вы организуете свой ДОМЕН?

    Могу ли я заставить Ctrl-C в дочернем процессе выполнять некоторые действия в родительском процессе?

    потерянный загрузчик FreeBSD efi после обновления Windows 10

    Linux и Unix - лучшая ОС в мире.