2014-03-27 59 views
1

我有内容的示例文件:SED正则表达式失败

Filesystem           512-blocks  Used Available Capacity iused  ifree %iused Mounted on 
/dev/disk0s2          467182912 419318824 47352088 90% 52478851 5919011 90% /
devfs              419  419   0 100%  727   0 100% /dev 
/dev/disk1s2          975093952 673515008 301578944 70% 84189374 37697368 69% /Volumes/Local_Storage 
map -hosts             0   0   0 100%   0   0 100% /net 
map auto_home            0   0   0 100%   0   0 100% /home 
localhost:/l3ZTI82fIEDeEEIvUkf44A     467182912 467182912   0 100%   0   0 100% /Volumes/MobileBackups 
/dev/disk2s2          1952853344 1925763856 27089488 99% 240720480 3386186 99% /Volumes/SK Backup 
/dev/disk3s2          199328216 88909928 110418288 45% 11113739 13802286 45% /Volumes/Secure_Storage 
/dev/disk4s2           59328216 51456432 7871784 87% 6432052  983973 87% /Volumes/Secure 
/dev/disk5s2           60000000 12713448 47286552 22% 1589179 5910819 21% /Volumes/Secure_Personal 
//[email protected]/Storage 4294701048 1128302984 3166398064 27% 141037871 395799758 26% /Volumes/Storage 
/dev/disk6s2           200000  9952  190048  5%  1242  23756 5% /Volumes/VAULT 
//[email protected]/chris.s   467182912 437521864 29661048 94% 54690231 3707631 94% /Volumes/chris.schmitz 
//[email protected]/NET    167563256 50264576 117298680 30%   0 18446744073709551615 0% /Volumes/NETLOGON 

而且我的工作从文件拉出只是IP地址和主机名。现在我正在使用下面的模式抓住了IPS:

cat dfsample.txt | awk '/@/' | sed -E 's/.*([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/g' 

意想不到的结果:

//[email protected]/Storage 4294701048 1128302984 3166398064 27% 141037871 395799758 26% /Volumes/Storage 
2.20.1.76 
//[email protected]/NET    167563256 50264576 117298680 30%   0 18446744073709551615 0% /Volumes/NETLOGON 

我对sed的部分期望是,.*之前和定义的模式后, parens会选择整条线,当我使用\1替代在parens中发现的模式的线时,它会用找到的模式替换整条线,只留下ip地址。

由于某种原因,我的IP地址的前两位数字被切断。当我尝试在崇高的模式在崇高它发现IP没有问题。我错过了什么?

回答

1
sed -nr 's,^//[^@/]*@([^/]*)/.*,\1,p' 

获取主机名和IP地址,并且不会被“有趣的”卷名所迷惑。

如果您的SED没有r标志,转义是不是在这一个太丑陋了,我也许应该给它只是这样说:

sed -n 's,^//[^@/]*@\([^/]*\)/.*,\1,p' 

(编辑:[^@] - >[^@/]安全播放)

+0

+1提供完整的解决方案;使用'-E'代替'-r'应该为OP工作(顺便说一句,'-E'也可以与GNU'sed'一起工作(作为'-r'的别名),但没有记录)。 – mklement0

+0

因此,如果我正确理解这一点,第一个sed节中的正则表达式基本上是说“找到所有以双正斜杠开始的行,0个或多个不是”@“的字符,直到达到”@“,然后为零或更多不是正斜杠的字符(记住这个模式),直到你得到一个正斜杠,然后有零个或多个不包含一个新行的字符,并用存储的模式替换它并打印它“,对吗?这很有道理,我只是想确保我完全理解模式背后的原因。 –

+0

你已经明白了。 @ mklement0谢谢! – jthill

2

问题是,您sed默认情况下会打印行,无论模式匹配与否。使用-n禁用的模式空间和p自动打印功能在当前模式空间:

sed -En '/@/{s/.*([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*/\1/p;}' inputfile 

这将产生2.20.1.76您的输入。另外请注意,您不需要管道awk来过滤数据。

+0

+1;为了使它在OSX上工作,'''必须在关闭'}'之前执行(或者,不要将's'命令放在'{...}'中)。 – mklement0

+0

@ mklement0 BSD sed现在应该很开心':)' – devnull

+0

:) OP没有这么明确地说,但是'-E'的使用表明OSX/BSD。 – mklement0

1

这里是如何与awk

awk '/@/ {split($1,a,"[@/]");print a[4]}' file 
SK-HQ-SRV05.internal.com 
172.20.1.76 
hq-srv03 

此找到所有线无线做然后分割线@/
然后它从分割打印部分4