sed для замены нескольких строк и вывода в один файл

У меня есть текстовый файл, как показано ниже

name: xyz
ip: x.x.x.x
network: abc
gateway: def

name: xyz
ip: x.x.x.x
network: abc
gateway: def

Выше 2 блоков кода, я хочу написать многострочную команду sed, которая может заменить информацию "name" и "network", а затем перенаправить ее в тот же файл

Я попробовал ниже

while read line; do

cat $line 2> /dev/null | sed -i s/xyz/abc/g;s/network:.*/network: temp_net/g test.txt > ~/temp-file.txt

done

Приведенная выше команда заменяет только часть "сеть" из текстового файла, но не заменяет часть "имя".

Эксперты sed/bash plesae пролили свет на то, как использовать команду sed для замены нескольких объектов и перенаправления вывода в файл temp.txt?

Спасибо

3 ответа

Ваш while read Цикл здесь не имеет смысла. Ваша команда sed уже делает то, что вы хотите:

$ cat file
name: xyz
ip: x.x.x.x
network: abc
gateway: def

name: xyz
ip: x.x.x.x
network: abc
gateway: def
$ sed 's/xyz/abc/; s/network:.*/network: temp_net/' file
name: abc
ip: x.x.x.x
network: temp_net
gateway: def

name: abc
ip: x.x.x.x
network: temp_net
gateway: def

Обратите внимание, что я заключил вашу однострочную строку в одинарные кавычки и удалил g модификаторы от каждой замены, которые не нужны, так как вы собираетесь выполнять только одну замену на строку.

Неясно, хотите ли вы перезаписать исходный файл или нет - кажется, вы пытаетесь сделать оба в данный момент. Если вы хотите перезаписать ваш входной файл (и ваша версия sed поддерживает его), вы можете использовать -i переключатель:

sed -i 's/xyz/abc/; s/network:.*/network: temp_net/' file

Это перезапишет file, Некоторые версии sed требуют, чтобы вы указали суффикс для файла резервной копии:

sed -i.bak 's/xyz/abc/; s/network:.*/network: temp_net/' file

В этом случае, file все еще перезаписывается, но резервная копия оригинала сделана в file.bak,

Если вы просто хотите вывести результат в новый файл, все, что вам нужно, это простое перенаправление:

sed 's/xyz/abc/; s/network:.*/network: temp_net/' file > new_file

sed это неправильный инструмент для любой задачи, включающей многострочные блоки ввода, потому что он ориентирован на строки. Вы должны использовать awk, так как он ориентирован на запись и может легко обрабатывать каждый многострочный блок ввода, так как sed может обрабатывать строки ввода.

$ awk -v RS= -v ORS='\n\n' '{sub(/xyz/,"abc"); sub(/network:[^\n]+/,"network: temp_net")}1' file
name: abc
ip: x.x.x.x
network: temp_net
gateway: def

name: abc
ip: x.x.x.x
network: temp_net
gateway: def

Запустите это как awk '...' file > tmp && mv tmp file изменить исходный файл, или вы можете использовать awk -i inplace '...' file если у вас GNU awk 4.*.

Если вы просто пытаетесь поменять местами текст, я, вероятно, объединю seds в цепочку, а затем сохраняю вывод во временном файле, а затем возвращаю его обратно в исходный файл - возможно, это не лучшее решение, но первое, что приходит на ум.

У меня есть это в script.sh

#!/bin/bash
while read line
do

echo $line | sed s/xyz/temp1/g | sed s/abc/temp2/g | sed s/temp1/abc/g | sed s/temp2/xyz/g


done < $1 > $2

cat $2 > $1

Тогда вы можете просто запустить:

chmod +x script.sh
./script.sh input.txt output.txt

Надеюсь, это поможет.

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