Как добавить строку прежде и после строки с помощью sed

У меня есть форма строк вывод команды, как дали ниже.

service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started

Я хочу добавить строку прежде и после строки, которые указывают [Z] только. Таким образом, результат может прибыть как:

<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

Может любой помогать мне сделать это. Ваша справка значительно ценится.

я попробовал ниже, но это изменяет всю строку от вывода

sed -i "s/.*/<font color="red">&<\/font>/"
2
задан 4 September 2015 в 00:31

3 ответа

Вы были достаточно близки со своей попыткой; все, что необходимо было сделать, должно было сузить выполнение замены только к строкам, содержащим [Z] в конце:

sed -i '/\[Z\]$/ s/.*/<font>&<\/font>/' infile

Однако вот другой awk решение:

awk '$4=="[Z]" {printf("%s%s%s\n", "<font>", $0, "</font>"); next} {print}' infile
  • $4=="[Z]": шаблон; если 4-е поле в настоящее время обрабатываемой записи [Z], выполняет следующее действие; иначе это пропускает к следующему шаблону / действие;
  • printf("%s%s%s\n", "<font>", $0, "</font>"): печать <font>, в настоящее время обрабатываемая запись и </font> как строки, сопровождаемые новой строкой;
  • next: пропуски к следующей записи;
  • print: печатает в настоящее время обрабатываемую запись, сопровождаемую новой строкой;

Демонстрационный вывод:

user@debian ~ % cat infile
service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started
user@debian ~ % awk '$4=="[Z]" {printf("%s%s%s\n", "<font>", $0, "</font>"); next} {print}' infile
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started
2
ответ дан 2 December 2019 в 01:37

Можно использовать это:

sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p' file.txt

Поскольку Вы будете использовать его по STDOUT другой команды, так используйте его в качестве, например:

some command | sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p'

Это в основном имеет две части:

  • /\[Z\]$/ s/^/<font>/ будет соответствовать строке, которая имеет [Z] наконец, затем добавит <font> в начале строки s/^/<font>/

  • /\[Z\]$/ s/$/<\/font>/ будет соответствовать [Z] в конце строки и затем добавит </font> в конце использования строки /$/<\/font>/.

Пример:

$ cat file.txt 
service:clus1-svr          clus1-node2                      started    [Z]
service:clus1-svr          clus1-node2                      started

$ sed -n '/\[Z\]$/ s/^/<font>/;/\[Z\]$/ s/$/<\/font>/p' file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

Поскольку @glennjackman указал, что можно также использовать группирующуюся конструкцию, чтобы сделать все замены для единственного соответствия:

$ sed -n '/\[Z\]$/ { s/^/<font>/; s/$/<\/font>/p }' file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>

Как насчет a bash решение:

while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done <file.txt

Можно использовать его как:

some command | while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done

Это использует ту же логику в качестве sed один. Если концы строки с [Z] ([[ $line =~ \[Z\]$ ]]), затем строка печатается в нужном формате.

Пример:

$ while IFS= read -r line; do [[ $line =~ \[Z\]$ ]] && echo "<font>${line}</font>"; done <file.txt 
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
4
ответ дан 2 December 2019 в 01:37

Awk версия.

Протестированный с примером OP, вставляемым дважды в тот же файл, поэтому как Вы видите, это редактирует те две строки, которые имеют [Z], и два, которые не содержат его

  $ awk ' {if ($0~/\[Z\]/)  print "<font>"$0"</font>";else print}' testfile.txt                                                                   
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started
<font>service:clus1-svr          clus1-node2                      started    [Z]</font>
service:clus1-svr          clus1-node2                      started

Для вывода редактирований в файл используйте следующую конструкцию:

awk ' {if ($0~/\[Z\]/) print "<font>"$0"</font>";else print}' testfile.txt > /tmp/tmp.txt && cat /tmp/tmp.txt > testfile.txt

1
ответ дан 2 December 2019 в 01:37

Другие вопросы по тегам:

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