2017-01-10 4 views
0

У меня есть файл в этой схеме:Заменить блок текста

Some text 
--- 

## [Unreleased] 
More text here 

Мне нужно заменить текст между «---» и «## [Unreleased]» с чем-то еще в сценарии оболочки ,
Как это можно сделать с помощью sed или awk?

ответ

1

Перл на помощь!

perl -lne 'my @replacement = ("First line", "Second line"); 
      if ($p = (/^---$/ .. /^## \[Unreleased\]/)) { 
       print $replacement[$p-1]; 
      } else { print }' 

Триггер оператор .. говорит вам ли вы между двумя строками, кроме того, она возвращает номер строки относительно диапазона.

0
awk -v RS="\0" 'gsub(/---\n\n## \[Unreleased\]\n/,"something")+1' file 

дайте этой строке попробовать.

+0

Именно то, что я искал! Спасибо. –

0

Этот пример может помочь вам.

$ cat f 
Some text 
--- 

## [Unreleased] 
More text here 

$ seq 1 5 >mydata.txt 

$ cat mydata.txt 
1 
2 
3 
4 
5 

$ awk '/^---/{f=1; while(getline < c)print;close(c);next}/^## \[Unreleased\]/{f=0;next}!f' c="mydata.txt" f 
Some text 
1 
2 
3 
4 
5 
More text here 
1

Это может работать для вас (GNU СЭД):

sed '/^---/,/^## \[Unreleased\]/c\something else' file 

Изменение линии между двумя регулярного выражения к искомой строки.

+0

Красиво сделано. Чтобы заставить его работать с BSD 'sed', после' c \ 'требуется явная строка новой строки; используя строку '$ '...'' в 'bash':' sed -e $ '/^--- /,/^ ## \\ [Unreleased \\]/c \\\ nsomething else' file' – mklement0

0

awk решение, которое:

  • является портативным (POSIX-совместимых).
  • может обрабатывать любое количество строк между начальной и конечной строками блока и, возможно, с несколькими блоками (хотя все они будут заменены одним и тем же текстом).
  • читает файл по строкам (в противоположность чтению всего файла за раз).
awk -v new='something else' ' 
/^---$/ { f=1; next }        # Block start: set flag, skip line 
f && /^## \[Unreleased\]$/ { f=0; print new; next } # Block end: unset flag, print new txt 
! f             # Print line, if before or after block 
' file 
Смежные вопросы