Linux sed删除#和#之间的字符并添加:';bash脚本中有什么?

Linux sed删除#和#之间的字符并添加:';bash脚本中有什么?,linux,bash,sed,awk,grep,Linux,Bash,Sed,Awk,Grep,我正在编写一个处理OUI mac地址数据库()的脚本。示例输出如下所示: 40-25-C2 (hex) Intel Corporate 4025C2 (base 16) Intel Corporate Lot 8, Jalan Hi-Tech 2/3 Kulim Hi-Tech Park Kulim Kedah 09000 MAL

我正在编写一个处理OUI mac地址数据库()的脚本。示例输出如下所示:

  40-25-C2   (hex)      Intel Corporate
  4025C2     (base 16)      Intel Corporate
                Lot 8, Jalan Hi-Tech 2/3
                Kulim Hi-Tech Park
                Kulim Kedah 09000
                MALAYSIA

  40-27-0B   (hex)      Mobileeco Co., Ltd
  40270B     (base 16)      Mobileeco Co., Ltd
                #2126, IT Tower B, Keumkang Penterium Bldg, 810
                Kwanyang-Dong, Dongan-Ku
                Anyang City Kyunggi-Do 431810
                KOREA, REPUBLIC OF
40:25:C2 Intel Corporate
40:27:0B Mobileeco Co., Ltd
最后,我希望每一行都像这样:

  40-25-C2   (hex)      Intel Corporate
  4025C2     (base 16)      Intel Corporate
                Lot 8, Jalan Hi-Tech 2/3
                Kulim Hi-Tech Park
                Kulim Kedah 09000
                MALAYSIA

  40-27-0B   (hex)      Mobileeco Co., Ltd
  40270B     (base 16)      Mobileeco Co., Ltd
                #2126, IT Tower B, Keumkang Penterium Bldg, 810
                Kwanyang-Dong, Dongan-Ku
                Anyang City Kyunggi-Do 431810
                KOREA, REPUBLIC OF
40:25:C2 Intel Corporate
40:27:0B Mobileeco Co., Ltd
我不知道最好的办法是什么,到目前为止,我一直在一步一步地做这件事,这就是我到目前为止所做的

sed '/base 16/!d' test.txt > test1.txt  # delete all extra lines
sed 's/^...//' test1.txt > test2.txt    # delete 3 spaces at the beginning of each line
下一步将删除空格和(基数16),我似乎无法让它工作。。。或者我将如何添加:'s

除非有更好的办法

我还需要在osx和ubuntu中运行这个


提前谢谢

一种方法是说:

sed -r -n '/base 16/{s/\s+(..)(..)(..)\s+\([^)]*\)\s+/\1:\2:\3 /p}' test.txt
对于您的输入,它将产生:

40:25:C2 Intel Corporate
40:27:0B Mobileeco Co., Ltd

或者,你可以说:

sed -n '/base 16/{s/\s*\(..\)\(..\)\(..\)\s*([^)]*)\s*/\1:\2:\3 /p}' test.txt

这应该可以在Ubuntu和OSX上使用。

@devnull的建议在POSIX sed中重写:

sed -n '/base 16/{s/[[:blank:]]*\(..\)\(..\)\(..\)[[:blank:]]*([^)]*)[[:blank:]]*/\1:\2:\3 /p;}' file

结尾的右大括号需要在前面加一个分号。

这里有一种使用
awk
的方法:

awk '{ sub("\n.*",""); gsub("-",":",$1); $2="" }1' RS= file
结果:

40:25:C2  Intel Corporate
40:27:0B  Mobileeco Co., Ltd
40:25:C2 Intel Corporate
40:27:0B Intel Corporate Mobileeco Co., Ltd

尽管上面的解决方案很好,但输出中仍然有一个额外的空间,它通过只查看每条记录的第一行来作弊。在阅读了上面的代码之后,您似乎只对每条记录的第二行感兴趣,即包含“base 16”的行。下面是另一个使用
awk
解决这些问题的解决方案。为了便于阅读,我将其分为多行:

awk '{
    n = split($2, a, OFS);

    gsub(/..\B/,"&:",a[1]);

    for (i=4;i<=n;i++) { 

        r = (r ? r OFS : "") a[i]; 
    }

    print a[1], r

}' FS="\n" RS= file

这里是另一个
awk

awk -F") +" '/hex/ {split($1,a," ");gsub(/-/,":",a[1]);print a[1],$2}' file
40:25:C2 Intel Corporate
40:27:0B Mobileeco Co., Ltd

感谢您的快速响应!我有没有办法改变它,让它同时在osx和ubuntu上运行?脚本将需要在这两个版本上使用,并且osx没有-rTanks供您帮助,但仍然有一个问题$sed-n'/base 16/{s/\s*(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)(..)似乎BSD sed(在osx上)的支持更加有限。请尝试
grep“base 16”test.txt sed's/\s*(..\)\(..\)\(..\)\s*([^)]*)\s*/\1:\2:\3/'
如果你的Ubuntu
sed
没有
-r
就不能识别
\s
,试着用
[:space:]
替换每个
\s
。也许您还需要将任何
x+
替换为
xx*
,这很麻烦,但便于携带。最后,最可移植的解决方案可能是等效的Perl脚本。(提示:
s2p
)如此接近,我现在从grep命令获得4025C2::Intel Corporate