2016-11-22 5 views
0

Я пытаюсь написать сценарий, который изменит строку в файле на основе строки. Я не могу определить правильный синтаксис sed, если строка содержит как пробелы, так и скобки.Необходимая помощь SED

Оригинал Строка:

:INPUT DROP [0:0] 

необходимых изменений:

:INPUT ACCEPT [0:0] 

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

#!/bin/bash 
File=/etc/sysconfig/iptables 
String=":INPUT" 
sed -i -e "/$String/ s/DROP/ACCEPT/" $File 
+0

Просто, как большая часть исходной строки считается фиксированной и подходит для сравнения? В крайнем случае вы можете просто сопоставить всю строку и заменить ее: 'sed -i -e 's/^: INPUT DROP [0: 0] $ /: INPUT ACCEPT [0: 0] /'' – chepner

ответ

0

Если вы хотите заменить все DROP S для Iptables цепи с ACCEPT с, использовать якорь для начала строки:

String=':INPUT' 
sed -i -e 's/^\(*'"$String"' *\)DROP/\1ACCEPT/' "$File" 

Команда захватывает $String рисунок в начале строки (^) с рядом дополнительных пространств (*) и ссылается на захваченное содержимое с помощью \1.

Если, однако, вы хотите, чтобы соответствовать всей линии, использовать якорь для конца строки ($), а также:

sed -i -e 's/^\(*'"$String"' *\)DROP\(*\[0:0\] *\)$/\1ACCEPT\2/' "$File" 

Вы, вероятно, хотите, чтобы выражение немного более гибким, позволяя любому количество цифр для [<packet-counter>:<byte-counter>] пары, так как счетчики не имеет значения для логики правил Iptables:

sed -i -e 's/^\(*'"$String"' *\)DROP\(*\[[0-9]\+:[0-9]\+\]\)$/\1ACCEPT\2/' \ 
    "$File" 

команда выше заменяет запись сохраненного IPTables файла следующим образом:

< :INPUT DROP [0:0] 
< :INPUT DROP [618709275:676424577017] 
--- 
> :INPUT ACCEPT [0:0] 
> :INPUT ACCEPT [618709275:676424577017] 

Также обратите внимание на использование двойных кавычек. Закрытие переменной в двойных кавычках предотвращает переинтерпретацию специальных символов, кроме $, backtick и \. В противном случае вы рискуете применить команду к нескольким файлам (если, например, $File содержит *).

1

С GNU СЭД:

sed -i -r 's/(:INPUT)DROP(\[0:0\])/\1ACCEPT\2/' file 
Смежные вопросы