Назад | Перейти на главную страницу

BASH - sed заменяет варианты IP

Прошло некоторое время с тех пор, как я разместил здесь вопрос. Мне нужна помощь, чтобы заставить мой sed работать. Я пробовал все виды вариантов sed, но, похоже, это не работает. У меня есть файл, в котором есть «192. *», и мне нужен IP-адрес любого типа, который имеет хоть какое-то сходство с «192», все удалено, но мне нужно буквально сохранить все остальное. Что-то вроде:

+ : root : 192.,local,10.
+ : root : local,192.
+ : root : local,192.,10.
+ : root : local,10.33.45.34,192.168.22.100
+ : root : local,192.168.22.100,10.33.45.34
+ : root : local,192.168
+ : root : local,192.168,10.

Товар, который я пробовал:

sed -e 's/,192.*$//g' -e 's/,192.*,//g' -e 's/192.,//g'
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.,//' 
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.*,//' 
sed -e 's/,192.*$//' -e 's/,192.*,//' -e 's/192.,//'

Я чуть не сошел с ума, так что помощь приветствуется.

Заранее спасибо.

Я проверил этот sed, и он почти работает

sed -e 's/,\?192\(\.\([0-9]\{0,3\}\)\)\{0,3\},\?//g'

Например:

[batchhercules@hercules ~]$ cat example.txt | sed -e 's/,\?192\(\.\([0-9]\{0,3\}\)\)\{0,3\},\?//g'
+ : root : local,10.
+ : root : local
+ : root : local10.
+ : root : local,10.33.45.34
+ : root : local10.33.45.34
+ : root : local
+ : root : local10.

Как вы можете видеть в строке 3,5,7, здесь заменяются две запятые, что плохо. Итак, обновлено:

sed -e 's/,192\(\.\([0-9]\{0,3\}\)\)\{0,3\}//g' -e 's/192\(\.\([0-9]\{0,3\}\)\)\{0,3\},//g'

Что для вашего примера будет работать очень хорошо:

[batchercules@hercules ~]$ cat example.txt | sed -e 's/,192\(\.\([0-9]\{0,3\}\)\)\{0,3\}//g' -e 's/192\(\.\([0-9]\{0,3\}\)\)\{0,3\},//g'
+ : root : local,10.
+ : root : local,10.134.
+ : root : local,10.
+ : root : local,10.33.45.34
+ : root : local,10.33.45.34
+ : root : local
+ : root : local,10.

Мое предложение: используйте Perl.

куда perl-test это файл, содержащий данные в OP:

$ perl -pe 's/(?:(\s)192.*?(?:,|$))|(?:,192.*?(,|$))/$1$2/g' perl-test 
+ : root : local,10.
+ : root : local
+ : root : local,10.
+ : root : local,10.33.45.34
+ : root : local,10.33.45.34
+ : root : local
+ : root : local,10.

Вы можете так же легко выловить содержимое и переместить его в perl -pe....

Парсинг регулярных выражений Perl очень похож на sed, но более мощный.

Пояснение:

(?:) - Предоставление содержимого круглых скобок ?: делает это группа без захвата. Таким образом, круглые скобки, которые вы используете только для группировки, не влияют на обратную ссылку. $1 и $2 переменные, которые вы используете в своей строке замены.

(\s) - Захватывает пробелы, которые будут использоваться как $ 1 в строке замены. Вам нужно сопоставить 192 IP-адрес, которому предшествует пробел, чтобы вы могли распознать его как начало списка и сохранить запятую, которая следует за ним. Вы по-прежнему хотите оставить пробелы.

192.*? - Нежадный матч. Соответствует запятой до СЛЕДУЮЩЕЙ. Поведение по умолчанию в Perl (и ЕДИНСТВЕННОЕ поведение в sed) - соответствовать ПОСЛЕДНЕЙ запятой. Это не то, что вам нужно, и вы увидите разницу в списках с более чем тремя IP-адресами.

(?:,|$) - Группа без захвата сообщает, что ненадежное совпадение должно заканчиваться первой запятой или концом строки.

| - Очевидно, заменяет следующее регулярное выражение для соответствия.

,?192.*? - Нежадное совпадение для 192, которое НЕ находится в начале списка.

(,|$) - Как и раньше, сопоставьте первую запятую после IP-адреса 192. В этом случае вам НЕОБХОДИМО записать запятую. Вы хотите сохранить его, так как вы избавились от предыдущей запятой с помощью ,?192.*? и за ним может быть еще один элемент в списке. Конечно, если в списке, следующем за ним, НЕТ другого элемента, вы сопоставите конец строки $. Ссылка $ так как $2 в строке замены просто ничего не сделает; ссылка , подготовит вас к следующему пункту списка. Так что вы в любом случае прикрыты.

Надеюсь, в этом есть какой-то смысл!