BASH: Разделить MAC-адрес - от 000E0C7F6676 до 00: 0E: 0C: 7F: 66: 76

Hy,

Может ли кто-нибудь помочь мне с разделением MAC-адресов из файла журнала? :-)

Этот:

000E0C7F6676

должно быть:

00:0E:0C:7F:66:76

Atm я разделил это с OpenOffice, но с более чем 200 MAC-адресами, это очень скучно и медленно ...

Было бы неплохо, если бы решение было в bash. :-)

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


person fwaechter    schedule 16.07.2010    source источник
comment
это просто список MAC-адресов, или в файле есть что-то еще?   -  person falstro    schedule 16.07.2010
comment
см. stackoverflow.com/questions/1187078/   -  person tanascius    schedule 16.07.2010
comment
В файле есть и другие данные. Теперь он работает с небольшим обходным путем и вашим фрагментом. Спасибо вам всем. :-)   -  person fwaechter    schedule 19.07.2010


Ответы (7)


Это должен сделать простой сценарий sed.

sed -e 's/[0-9A-F]\{2\}/&:/g' -e 's/:$//' myFile

Это возьмет список MAC-адресов в myFile, по одному в строке, и вставит «:» после каждых двух шестнадцатеричных цифр и, наконец, удалит последний.

person falstro    schedule 16.07.2010
comment
Спасибо, попробую это. :-) - person fwaechter; 16.07.2010
comment
@Питер; Обратите внимание, что это довольно опасный способ сделать это, и он будет работать ТОЛЬКО в этом конкретном случае. Это лишь ненамного лучше, чем sed -e 's/../&:/g' -e 's/:$//' myFile, что на самом деле может быть лучше, поскольку это проще. - person falstro; 16.07.2010
comment
Да, я это видел. Но это работает, и этот фрагмент будет использоваться примерно 10 раз в год. Так что все нормально. В этом случае нет необходимости в идеальном решении. Спасибо за ваш ответ и ваш комментарий. :-) - person fwaechter; 19.07.2010
comment
Возможно, стоит отметить, что это работает только с прописными шестнадцатеричными цифрами, если вы хотите и нижний регистр, вы должны добавить a-f в скобки сразу после A-Z, чтобы в итоге получилось что-то вроде sed -e 's/[0-9A-Fa-f]\{2\}/&:/g' -e 's/:$//' myFile - person Brad P.; 18.12.2015

Чистый Баш. Этот фрагмент

mac='000E0C7F6676'

array=()
for (( CNTR=0; CNTR<${#mac}; CNTR+=2 )); do
  array+=( ${mac:CNTR:2} )
done
IFS=':'
string="${array[*]}"
echo -e "$string"

отпечатки

00:0E:0C:7F:66:76
person Fritz G. Mehner    schedule 16.07.2010

$ perl -lne 'print join ":", $1 =~ /(..)/g while /\b([\da-f]{12})\b/ig' file.log
00:0E:0C:7F:66:76

Если вы предпочитаете сохранить его как программу, используйте

#! /usr/bin/perl -ln    
print join ":" => $1 =~ /(..)/g
  while /\b([\da-f]{12})\b/ig;

Пробный прогон:

$ ./macs file.log 
00:0E:0C:7F:66:76
person Greg Bacon    schedule 16.07.2010

imo, регулярные выражения - неправильный инструмент для строки фиксированной ширины.

perl -alne 'print join(":",unpack("A2A2A2A2A2A2",$_))' filename

Или
gawk -v FIELDWIDTHS='2 2 2 2 2 2' -v OFS=':' '{$1=$1;print }'

Это немного забавно с заданием по изменению поведения печати. Может быть более понятным будет просто напечатать 1, 2, 3, 4, 5, 6 долларов

person frankc    schedule 16.07.2010
comment
Обыграй меня ... знал, что gawk должен иметь ответ :-) - person Chris J; 16.07.2010

Требуется версия Bash> = 3.2

#!/bin/bash
for i in {1..6}
do
    pattern+='([[:xdigit:]]{2})'
done

saveIFS=$IFS
IFS=':'
while read -r line
do
    [[ $line =~ $pattern ]]
    mac="${BASH_REMATCH[*]:1}"
    echo "$mac"
done < macfile.txt > newfile.txt
IFS=$saveIFS

Если ваш файл содержит другую информацию, помимо MAC-адресов, которую вы хотите сохранить, вам необходимо изменить регулярное выражение и, возможно, переместить манипуляцию IFS внутри цикла.

К сожалению, в Bash нет эквивалента sed 's/../&:/', использующего что-то вроде ${mac//??/??:/}.

person Dennis Williamson    schedule 16.07.2010
comment
Спасибо, это очень плохо (я имею в виду ${mac//??/??:/} часть). - person falstro; 19.07.2010

a='0123456789AB'
m=${a:0:2}:${a:2:2}:${a:4:2}:${a:6:2}:${a:8:2}:${a:10:2}

результат:

01:23:45:67:89:AB
person Zibri    schedule 11.02.2021

person    schedule
comment
Вы знаете, как заставить это работать: ${mac//??/??:/}, то есть знаете, как получить то, что было расширено в заменяемой части? - person falstro; 16.07.2010
comment
+1 Оберните это в for mac in $(cat file-with-macs.txt); do { ... }, и это будет хорошее, чистое решение bash для всей проблемы OP. - person Dan Moulding; 16.07.2010
comment
@Dan: Нет, это должно быть while read -r line; do ...; done < file-with-macs.txt. @roe: Смотри мой ответ. - person Dennis Williamson; 17.07.2010