0

我正在使用 linux 和 bash。我有一个文本文件,其中包含其他程序在运行时生成的上下文。文本文件的长度、行数和内容不时发生变化。但是文中有一些模式没有改变,一个典型的例子是

123098230984LD#2e3 123098230984LD#23234 XER_3424324_23424 33:34:35: 节点:9-72-1408 &82 &34 $1231313 *3435322 链接到端口:323 3424242424LD#2234 2424332

在这里,我想提取模式“node:NUMBER-NUMBER-NUMBER”和“port:NUMBER”,但它在文本中出现的位置也不时变化。现在我手动提取信息。我想知道是否有任何方法可以自动提取信息。真正困难的是每次生成文件时内容都会发生变化。

4

1 回答 1

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

这些.*位仅代表任何垃圾,括号用于“捕获”匹配的文本,以便可以在替换中使用它(as\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 系列的最后一个)。有关详细信息,请参见此处


而且,如果您需要变量中的实际值,您可以使用以下内容:

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实现的评论)。

于 2012-07-24T02:10:05.787 回答