我正在使用linux和bash。我有一个文本文件,其中包含由其他程序在运行时生成的上下文。文本文件的长度,行数和内容不时更改。但是文中有一些模式没有变化,一个典型的例子就是
123098230984LD#2E3 123098230984LD#23234 XER_3424324_23424 33:34:35:节点:9-72-1408& 82& 34 $ 1231313 * 3435322 link to port:323 3424242424LD#2234 332424LD#23424234
在这里,我想提取模式“node:NUMBER-NUMBER-NUMBER”和“port:NUMBER”,但它在文本中出现的位置也不时变化。现在我手动提取信息。我想知道是否有任何方法可以自动提取信息。每次生成文件时内容都会发生变化。
答案 0 :(得分: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
)。 / p>
<强>侧栏:强>
如果您的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
实施添加额外转义的评论。)