28 grep sed awk text-processing
是否可以使用sed,awk或进行多行模式匹配grep?举个例子,我想得到{和之间的所有线}
所以它应该能够匹配
1. {}
2. {.....}
3. {.....
.....}Run Code Online (Sandbox Code Playgroud)
最初将问题用作<p>示例。编辑了问题以使用{和}。
she*_*ter 22
虽然我同意上面的建议,除了微小的或完全是临时的之外,您还需要一个解析器,但(几乎;-)可以将大括号之间的多行块与 sed 匹配。
这是 sed 代码的调试版本
sed -n '/[{]/,/[}]/{
p
/[}]/a\
end of block matching brace
}' *.txt
Run Code Online (Sandbox Code Playgroud)
一些笔记,
/[{]/,/[}]/是一个范围表达式。这意味着扫描直到找到与第一个模式匹配的内容(/[{]/)然后扫描直到找到第二个模式(/[}]/)然后执行您在 sed 代码中的 { } 之间找到的任何操作。在这种情况下,'p' 和调试代码。(这里没有解释,使用它,修改它或将其取出最适合你)。当您满意地证明代码确实匹配由 {,} 分隔的块时,您可以删除块调试的 /[}]/a\ 结尾。
此代码示例将跳过不在花括号对内的任何内容。正如上面其他人所指出的,如果您在字符串、reg-exps 等中嵌入了任何额外的 {,},或者在右大括号是同一行的情况下,它会很容易混淆,(感谢 fred.bear)
我希望这有帮助。
Coo*_*per 14
您可以对 pcregrep 使用 -M(多行)选项:
pcregrep -M '\{(\s*.*\s*)*\}' test.txt
Run Code Online (Sandbox Code Playgroud)
\s 是空格(包括换行符),因此它匹配零次或多次出现的(空格后跟 .* 后跟空格),全部用大括号括起来。
更新:
这应该进行非贪婪匹配:
pcregrep -n -M '\{(\n*.*?\n*)*?\}' test.txt
Run Code Online (Sandbox Code Playgroud)
解析器.awk:
#!/usr/bin/awk -f
function die(msg) { print msg > "/dev/stderr"; exit 1 }
BEGIN {
FS=opener
if (mode=="l") linewise=1
else if (mode=="i") trim_closer=length(closer)
else if (mode!="a") die("mode must be one of: l,i,a")
}
{
live=level
for (f=1; f<=NF; f++) {
if (f>1) {
live=++level
if (mode=="i" && level>1 || mode=="a") printf "%s", opener
}
cur=$f
level-=gsub(closer, "", cur)
if (level<0) die("Unbalanced")
if (!linewise) {
cur=$f
if (sub(".*" closer, "", cur)) printf "%s",
substr($f, 1, length($f) - length(cur) - (level ? 0 : trim_closer))
else if (live) printf "%s", $f
}
}
if (live) {
if (linewise) print
else print ""
}
}
END { if (level>0) die("Unbalanced") }
Run Code Online (Sandbox Code Playgroud)
调用为awk -v'opener={' -v'closer=}' -v'mode=a' -f parser.awk。如果 mode 是a,它打印所有最外面的,平衡的括号和内容{...};如果 mode 是i,它只打印它们的内容;如果 mode 是l,它会打印最外层{...}开始、保持打开或关闭的完整行。