Bash, обрезать IP из строки, разделенной точками

Чтобы предотвратить дублирование записей в моем PATH, мне пришлось поместить следующее в ОБА профиль ~/.bash _и ~/.bashrc:

PATH=$(echo $(sed 's/:/\n/g' <<< $PATH | sort | uniq) | sed -e 's/\s/':'/g')

Главный недостаток заключается в том, что он сортирует записи PATH, но я думаю, что с этим можно смириться.

1
08.12.2020, 19:34
5 ответов

Сperl:

perl -pe 's/(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/$4.$3.$2.$1/g' < input

Это немного менее подробно и немного более разборчиво, чем стандартный sedэквивалент:

d='\([0-9]\{1,\}\)'
LC_ALL=C sed "s/$d\.$d\.$d\.$d\.in-addr\.arpa/\4.\3.\2.\1/g" < input

Они заменяют все вхождения <d1>.<d2>.<d3>.<d4>.in-addr.arpaна <d4>.<d3>.<d2>.<d1>(, где <dX>— любая последовательность одной или нескольких десятичных цифр ), оставляя все остальное нетронутым.

7
18.03.2021, 22:44
$ awk '{split($1,p,"."); $1=p[4]"."p[3]"."p[2]"."p[1]} 1' file
1.2.3.10 name hostname
5
18.03.2021, 22:44

Еще один perl-подход:

$ perl -lane '@ip=split(/\./,$F[0]); $F[0]=join(".",reverse(@ip[0..3])); print "@F"' file
1.2.3.10 name hostname

Обратите внимание, что здесь предполагается, что первые 4.-разделенных элемента строки являются IP-адресом.

Пояснение

  • -lane:-aзаставляет perlработать так же, как awk, разбивая каждую строку ввода на пробелы и сохраняя результат в массиве @F. -lдобавляет новую строку к каждому вызову print(и удаляет завершающие символы новой строки из входных строк ), -nозначает «читать ввод построчно и применять сценарий, заданный -eк каждому линия".
  • @ip=split(/\./,$F[0]):возьмите первое поле($F[0])и разделите его на ., сохранив вывод в массиве @ip.
  • $F[0]=join(".",reverse(@ip[0..3]));:это состоит из нескольких частей. Во-первых, join(CHAR, ARRAY)будет использовать символ CHAR для объединения элементов массива в строку. Здесь мы передаем первые 4 элемента (с индексами от 0 до 3 )массива @ip, так что все до чисел, отличных от -в вашем примере, поэтому объединение будет производить IP. Затем reverseпереворачивает его. Наконец, мы сохраняем результат как $F[0].
  • print "@F" :после предыдущих шагов массив @Fтеперь содержит то, что нам нужно, поэтому мы его печатаем.

Если все, что вам нужно, это удалить первое вхождение строки .in-addr.arpaиз всех строк вашего входного файла, а затем изменить IP-адрес, вы можете просто выполнить:

$ perl -pe 's/\.in-addr\.arpa//; s/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/$4.$3.$2.$1/' file
1.2.3.10 name hostname
2
18.03.2021, 22:44

Направьте несколько результатов на стандартный ввод этого скрипта:

while read ip n hn
do
  ip="$(awk -F. '{print $4 "." $3 "." $2 "." $1}' <<< "$ip")"
  printf '%s %s %s\n' "$ip" "$n" "$hn"
done
0
18.03.2021, 22:44

Другой способ — использовать встроенный цикл/прогон по строке в регулярном выражении. Мы настраиваем возврат в регулярном выражении и останавливаемся, когда он возвращается к началу.

$ perl -lne '
    m/(.*) ((?<!\d)\d+\.) (?{printf q(%s), $1?$2:$2=~s|\.||r}) (?(?{$1 ne ""}) (?!))/x;
    print /(\s\S.*)/;
' file
1.2.3.10 name hostname
0
18.03.2021, 22:44

Теги

Похожие вопросы