Awk или sed для добавления пропущенных нулей в ма c адресах - PullRequest
2 голосов
/ 21 апреля 2020

У меня есть файл, состоящий из IP-адресов и пар адресов MA C, и мне нужно дополнить адреса MA C нулями в каждом октете, но я не хочу менять IP. Итак, это ...

10.5.96.41 0:0:e:4c:b7:42
10.5.96.42 c4:f7:0:13:ef:32
10.5.96.43 0:e8:4c:60:2b:42
10.5.96.44 0:6a:bf:b:35:f1

Должно быть изменено на это ...

10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

Я пытался sed 's/\b\(\w\)\b/0\1/g', но это выдает:

10.05.96.41 00:00:0e:4c:b7:42
10.05.96.42 c4:f7:00:13:ef:32
10.05.96.43 00:e8:4c:60:2b:42
10.05.96.44 00:6a:bf:0b:35:f1

, что не желателен, потому что я хочу воздействовать только на часть адреса MA C.

Ответы [ 4 ]

4 голосов
/ 21 апреля 2020

Поскольку вы пометили macos, я не уверен, будет ли это работать для вас. Я проверил это на GNU awk

$ awk '{gsub(/\<[0-9a-f]\>/, "0&", $2)} 1' ip.txt
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

awk хорошо для обработки поля, здесь вы можете просто выполнить замену только для второго поля

Но, я вижу \b и \w с вашей командой sed, значит, вы используете GNU sed? Если это так,

sed -E ':a s/( .*)(\b\w\b)/\10\2/; ta' ip.txt


С perl

$ perl -lane '$F[1] =~ s/\b\w\b/0$&/g; print join " ", @F' ip.txt
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

Если вы хотите предпринять приключения, укажите, что вы хотите избежать замены первого поля:

perl -pe 's/^\H+(*SKIP)(*F)|\b\w\b/0$&/g' ip.txt
2 голосов
/ 21 апреля 2020

С любым sed, который использует -E для поддержки ERE, например, GNU sed или OSX / BSD (MacOS) sed:

$ sed -E 's/[ :]/&0/g; s/0([^:]{2}(:|$))/\1/g' file
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1

и с любым sed:

$ sed 's/[ :]/&0/g; s/0\([^:][^:]:\)/\1/g; s/0\([^:][^:]$\)/\1/' file
10.5.96.41 00:00:0e:4c:b7:42
10.5.96.42 c4:f7:00:13:ef:32
10.5.96.43 00:e8:4c:60:2b:42
10.5.96.44 00:6a:bf:0b:35:f1
1 голос
/ 21 апреля 2020

Это может сработать для вас (GNU sed):

sed 's/\b.\(:\|$\)/0&/g' file

Добавить перед 0 перед любым одиночным символом, после которого следует : или конец строки.

Other seds может использовать:

sed 's/\<.\(:\|$\)/0&/g' file
0 голосов
/ 21 апреля 2020

С GNU sed:

sed -E ':a;s/([ :])(.)(:|$)/\10\2\3/g;ta' file

с любым sed:

sed ':a;s/\([ :]\)\(.\):/\10\2:/g;ta' file

Пояснение (для версии GNU)

:a  # a label called 'a', used as a jump target
;   # command separator
s   # substitute command ...
/([ :])(.)(:|$)/ # search for any single char which is enclosed by
                 # either two colons, a whitespace and a colon or
                 # a colon and the end of the line ($)
                 # Content between () will be matched in a group
                 # which is used in the replacement pattern

\10\2\3          # replacement pattern: group1 \1, a zero, group2 and 
                 # group3 (see above)
/g               # replace as often as possible
;                # command separator
ta               # jump back to a if the previous s command replaced
                 # something (see below)

L oop необходимо использовать метку a и команду ta, потому что sed больше не будет соответствовать шаблону, если input уже был частью замены. Это может произойти в этом случае, например (первая строка):

0:0

Когда применяется вышеуказанный шаблон, sed заменит

<space>0: by <space>00: <- colon

То же двоеточие не будет совпадать снова, как начало: второго нуля. Поэтому l oop пока все не заменится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...