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
Надеюсь, это поможет.