Заменить строку после определенной строки

sed 's/\([^e]\)-/\1*/g' /path/to/input

Чтобы уточнить sedутверждение:

  • \([^e]\)-Здесь мы используем группировку для поиска любого символа, кроме e, за которым следует дефис
  • \1*-Здесь мы заменяем то, что было найдено, тем, что было в этой группе (i. г. не -e перед дефисом ), за которым следует звездочка, заменяющая этот дефис.

Обратите внимание, что это не будет работать с дефисами, которые являются первым символом строки; для этого нам придется добавить специальный случай:

sed 's/\([^e]\)-/\1*/g;s/^-/*/' /path/to/input

Это аналогично, но вместо дефиса, который является первым символом строки, используется звездочка. Так как это первый символ, ему не может предшествовать e.

1
22.08.2019, 20:46
5 ответов

Как насчет просто

sed '/task Listen/{n; s/edit TRIES 2/edit TRIES 3/}' file

Пр. дано

$ cat file
    edit TRIES 2
    edit TRIES 2
  task Listen
    edit TRIES 2
    edit TRIES 2

, затем

$ sed '/task Listen/{n; s/edit TRIES 2/edit TRIES 3/}' file
    edit TRIES 2
    edit TRIES 2
  task Listen
    edit TRIES 3
    edit TRIES 2
3
27.01.2020, 23:22

Это моя попытка:

sed -E 'N;s/([[:blank:]]*task Listen\n[[:blank:]]*edit TRIES )[0-9]*)/\13/' file

Используйте расширенные регулярные выражения:

sed -E

Используйте командуN(новая строка)

'N;

Сопоставьте и зафиксируйте две строки, если они начинаются с пробелов или табуляций, в любом повторе:

([[:blank:]]*task Listen\n[[:blank:]]*edit TRIES )[0-9]*

Замените строку захваченным шаблоном и нужной строкой, в данном случае3:

/\13/
0
27.01.2020, 23:22

Пробовал использовать команду «Нижний», все работает нормально

команда

sed -n '/task Listen/,+1p' filename| sed "s/edit TRIES 2/edit TRIES 3/g"

выход

task Listen
    edit TRIES 3
-1
27.01.2020, 23:22

Следующие сценарии sed основаны на идее, что строка, содержащая ноль -или -дополнительных пробелов и строка «задача Listen», определяет начало блока текста, который вы хотите отредактировать, и что блок продолжается до следующей «задачи» или до конца файла (, в зависимости от того, что наступит раньше ).

Это работает в тех случаях, когда строка 'edit TRIES 2' может не следовать сразу за строкой task Listen, а может быть в любом месте в блоке task Listen.

Он также справится с вариациями количества пробелов в строке edit TRIES 2.

sed -E -e '/^ *task Listen/,/^ *task/ {s/edit +TRIES +2 *$/edit TRIES 3/}'

Расширенные регулярные выражения включены (с -E), поэтому мы можем использовать+(1 -или -больше )без необходимости использовать обратную косую черту. Также используется для чередования (task|xyz)без искажения обратной косой черты во втором примере.

*$в конце регулярного выражения поиска гарантирует, что оно будет соответствовать только 2, а не какому-либо другому числу, начинающемуся с 2.

Например, если ввести это:

$ cat input.txt 
  task something
    edit TRIES 2
  task Listen
    foo
    bar
    edit TRIES 25
    edit TRIES 2
  task somethingelse
    edit TRIES 2

Будет получен следующий результат:

$ sed -E -e '/^ *task Listen/,/^ *task/ {s/edit +TRIES +2 *$/edit TRIES 3/1}' input.txt 
  task something
    edit TRIES 2
  task Listen
    foo
    bar
    edit TRIES 25
    edit TRIES 3
  task somethingelse
    edit TRIES 2

Обратите внимание, что a )не изменил ПОПЫТКИ 2 на ПОПЫТКИ 3 ни в предыдущем, ни в последующем блоке задач, а b )изменил ПОПЫТКИ 2 везде, где он появлялся в «задаче». Блок «Слушай». ПРИМЕЧАНИЕ. :, если в этом блоке более одного раза встречается «edit TRIES 2», все вхождения будут изменены.

Если блок «Прослушивание задачи» завершается или может заканчиваться чем-либо, кроме строки, начинающейся с нуля -или -дополнительных пробелов и слова «задача», вы можете изменить второй адрес в соответствии с. например. если блок может заканчиваться либо новым блоком задачи, либо блоком "xyz":

sed -E -e '/^ *task Listen/,/^ *(task|xyz)/ {s/edit +TRIES +2 *$/edit TRIES 3/1}'

Чтобы заставить любую из приведенных выше команд sed фактически изменить входной файл, а не только выходной поток,используйте опцию sed -i.

Наконец, если вводимый текст может содержать пробелы и/или символы табуляции вместо просто пробелов, вы можете использовать класс символов [[:blank:]]для их сопоставления. например.

 sed -E -e '/^[[:blank:]]*task Listen/,/^[[:blank:]]*task/ {
   s/edit[[:blank:]]+TRIES[[:blank:]]+2[[:blank:]]*$/edit TRIES 3/}'

или, если ваша версия sed поддерживает perl -совместимые регулярные выражения (, например. GNU-сед):

sed -E -e '/^\s*task Listen/,/^\s*task/ {s/edit\s+TRIES\s+2\s*$/edit TRIES 3/}'
0
27.01.2020, 23:22

Или с помощью редактора сценариевed:найдите строку, содержащую «task Listen», перейдите на одну дальше и замените любые «edit TRIES 2» на «edit TRIES 3»:

printf '%s\n' '/task Listen/+1 s/edit TRIES 2/edit TRIES 3/' 'wq' | ed -s file

printfотправляет две команды, разделенные новой строкой -, ed(, которому приказано подавить диагностику с помощью-s):

  1. /task Listen/+1--на следующем том, который соответствует «задаче Слушать»,
  2. s/edit TRIES 2/edit TRIES 3/--заменить любые «редактировать ПОПЫТКИ 2» на «редактировать ПОПЫТКИ 3»

Если строка, следующая за «task Listen», не содержит «edit TRIES 2», edзавершится безуспешно (и не изменит файл ).

1
27.01.2020, 23:22

Теги

Похожие вопросы