Прошло некоторое время с тех пор, как я разместил здесь вопрос. Мне нужна помощь, чтобы заставить мой 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
в строке замены просто ничего не сделает; ссылка ,
подготовит вас к следующему пункту списка. Так что вы в любом случае прикрыты.
Надеюсь, в этом есть какой-то смысл!