SED的单行 - 查找定界符对周围的关键字(sed one-liner - Find delimit

2019-09-19 22:57发布

我通常与大型XML文件的方式,一般通过做字数grep确认一定的统计数据。

例如,我要确保我有至少五个实例widget通过一个单一的XML文件:

cat test.xml | grep -ic widget

此外,我只是想能够登录该行widget出现,即:

cat test.xml | grep -i widget > ~/log.txt

不过,我真正需要的关键信息的XML代码块widget出现在示例文件可能看起来像:

<test> blah blah
  blah blah blah
  widget
  blah blah blah
</test>

<formula>
  blah
  <details> 
    widget
  </details>
</formula>

我试图从示例文本下面的输出上面,即:

<test>widget</test>

<formula>widget</formula>

实际上,我试图让与适用于XML文本/被周围的任意字符串代码块标记标签的最高水平单行widget

有没有人有通过命令行的一个班轮实施这有什么建议?

谢谢。

Answer 1:

同时使用非优雅的方式sedawk

sed -ne '/[Ww][Ii][Dd][Gg][Ee][Tt]/,/^<\// {//p}' file.txt | awk 'NR%2==1 { sub(/^[ \t]+/, ""); search = $0 } NR%2==0 { end = $0; sub(/^<\//, "<"); printf "%s%s%s\n", $0, search, end }'

结果:

<test>widget</test>
<formula>widget</formula>

说明:

## The sed pipe:

sed -ne '/[Ww][Ii][Dd][Gg][Ee][Tt]/,/^<\// {//p}'
## This finds the widget pattern, ignoring case, then finds the last, 
## highest level markup tag (these must match the start of the line)
## Ultimately, this prints two lines for each pattern match

## Now the awk pipe:

NR%2==1 { sub(/^[ \t]+/, ""); search = $0 }
## This takes the first line (the widget pattern) and removes leading
## whitespace, saving the pattern in 'search'

NR%2==0 { end = $0; sub(/^<\//, "<"); printf "%s%s%s\n", $0, search, end }
## This finds the next line (which is even), and stores the markup tag in 'end'
## We then remove the slash from this tag and print it, the widget pattern, and
## the saved markup tag

HTH



Answer 2:

 sed -nr '/^(<[^>]*>).*/{s//\1/;h};/widget/{g;p}' test.xml

版画

<test>
<formula>

如果打印你想要的确切格式桑达只有一个班轮会比较复杂。

编辑:
你可以使用/widget/I不是/widget/为不区分大小写的匹配widget在GNU sed的,否则使用[Ww]对于每个字母作为对方的回答。



Answer 3:

这可能会为你(GUN SED)工作:

sed '/^<[^/]/!d;:a;/^<\([^>]*>\).*<\/\1/!{$!N;ba};/^<\([^>]*>\).*\(widget\).*<\/\1/s//<\1\2<\/\1/p;d' file


Answer 4:

需要gawk有在正则表达式RS

BEGIN {
    # make a stream of words
    RS="(\n| )"
}

# match </tag>
/<\// {
    s--
    next
}

# match <tag>
/</ {
    if (!s) {
    tag=substr($0, 2)
    }
    s++
}

$0=="widget" {
    print "<" tag $0 "</" tag
}


文章来源: sed one-liner - Find delimiter pair surrounding keyword
标签: xml bash sed grep