2012-07-24 36 views
0

我正在使用linux和bash。我有一个文本文件,运行时由其他程序生成上下文。文本文件的长度,行数和内容会随时更改。但在文本一些图案不变,一个典型的例子是寻找一种方式从linux中的文本文件中提取模式

123098230984LD#2E3 123098230984LD#23234 XER_3424324_23424 33:34:35:节点:9-72-1408 $一二三一三一三 * 3435322 链接到端口:323 3424242424LD#2234 332424LD#23424234

在这里,我要提取的图案 “节点:NUMBER-NUMBER-NUMBER” 和 “端口:NUMBER”,但它在文本发生从改变不时有时间。现在我手动提取信息。我想知道是否有任何方法自动提取信息。什么使得真正困难的是每次生成文件时内容都会改变。

回答

0

可以使用sed通过摆脱不需要位的提取所需字段:

pax> echo 'junk node:9-72-1408 more junk port:323 last junk' 
    | sed -E 's/^.*(node:[0-9]+-[0-9]*-[0-9]*).*(port:[0-9]+).*$/\1 \2/' 
node:9-72-1408 port:323 

.*位只是代表任何垃圾和括号是用来“捕捉”匹配的文本,从而可用于更换(如\1\2)。


边栏:

如果你的的sed版本不支持-E的扩展正则表达式,它可以支持-r,与GNU sed的某些版本。

否则,您必须对括号进行转义和+字符:

pax> echo 'junk node:9-72-1408 more junk port:323 last junk' 
    | sed 's/^.*\(node:[0-9]\+-[0-9]\+-[0-9]\+\).*\(port:[0-9]\+\).*$/\1 \2/' 
node:9-72-1408 port:323 

为GNU的源代码包含的sed这个小片段:

/* Undocumented, for compatibility with BSD sed. */ 
    case 'E': 
    case 'r': 

,但是这似乎已经出台在4.2中(即它在4.2中,但不在4.1.5中,是4.1系列中的最后一个)。详情请参阅here


而且,如果你需要在变量的实际值,可以使用类似:

pax> inpstr='junk-here node:9-72-1408 more-junk port:323 last-junk' 

pax> node=$(echo "$inpstr" | sed -E 's/^.*node:([0-9]+-[0-9]+-[0-9]+).*$/\1/') 

pax> port=$(echo "$inpstr" | sed -E 's/^.*port:([0-9]+).*$/\1/') 

pax> echo $inpstr 
junk-here node:9-72-1408 more-junk port:323 last-junk 

pax> echo $node 
9-72-1408 

pax> echo $port 
323 

(考虑到有关使用-r或添加了早些时候的评论额外转义“较小” sed实现)。

+0

谢谢。我试过这个命令,但它似乎在我的系统中不起作用。我不知道为什么,在sed中没有-E选项,我的系统中的sed版本是GNU sed version 4.1.5。我尝试了男性sed,它只有-e或-expression,我也试过,但它没有给我预期的结果。它在's'命令的RHS“ – user1285419 2012-07-24 02:43:54

+1

@ user1285419上显示”sed:-e表达式#1,字符57:无效引用\ 2,请尝试使用扩展正则表达式而不是'-E'。 '-E'在我的GNUsed4.2.1上工作,即使它不在联机帮助页中。否则,你将不得不稍微修改正则表达式。我会更新答案。 – paxdiablo 2012-07-24 03:06:53

+0

@ user1285419:此外,'-E'开关已添加到4.2版本,这解释了为什么4.1.x没有它。但是,由于4.1.0具有'-r',因此您可以直接使用它。 – paxdiablo 2012-07-24 03:34:46

相关问题