2015-04-22 3 views
0

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

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

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

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

Я попытался ниже

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?

Спасибо

+0

Пожалуйста, не могли бы вы [изменить] ваш вопрос, чтобы уточнить, что вы пытаетесь сделать? Каков ваш желаемый результат? –

ответ

2

Ваш while read петля не служит никакой цели здесь. Ваш СЭД команда на самом деле делает то, что вы хотите уже:

$ 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 

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

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

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

Это будет перезаписывать file. Некоторые версии СЭД требуют указать суффикс для файла резервной копии:

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 
0

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

У меня есть это в 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 

Надежда, что помогает.

+0

Седельный трубопровод не требуется. 'sed 's/xyz/temp1/g; s/abc/temp2/g; s/temp1/abc/g; s/temp2/xyz/g'' будет выполнять ту же задачу, что и ваш конвейер. – anishsane

0

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. *.

+0

В чем преимущество обработки каждого блока в качестве записи в этом случае? –

+0

@TomFenech Что, когда OP осознает, что им захочется делать преобразования только в конкретные блоки, они могут просто добавить «/ ip: a.b.c.d /» или подобное предложение. Фактически нет реальных данных ОП, которые повторяют блоки с одинаковыми значениями. –