Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Awk中配对任意XML打开/关闭标记_Awk - Fatal编程技术网

在Awk中配对任意XML打开/关闭标记

在Awk中配对任意XML打开/关闭标记,awk,Awk,我试图提取如下所示的块注释: <tag_1:sub_tag> This is 1 comment. </tag_1:sub_tag> 这是一条评论。 或 这是另一个评论。 通过 find-键入f-exec awk'/',//{打印文件名“:“FNR”:“$0}”{}\; 但是我不知道如何让$variable接受任何东西,比如使用通配符*。有办法吗 这必须在子文件夹上递归完成 快来营救 awk '/<tag_1>/,/<\/tag_1>/

我试图提取如下所示的块注释:

<tag_1:sub_tag>
This is 1 comment.
</tag_1:sub_tag>

这是一条评论。


这是另一个评论。
通过

find-键入f-exec awk'/',//{打印文件名“:“FNR”:“$0}”{}\;
但是我不知道如何让$variable接受任何东西,比如使用通配符
*
。有办法吗

这必须在子文件夹上递归完成

快来营救

awk '/<tag_1>/,/<\/tag_1>/' file
awk'/',/'文件
如果要将标记名作为变量传递,可以将其更改为

 awk -v tag="tag_1" '$0~"<"tag">",$0~"</"tag">"' file
awk-v tag=“tag_1”'$0~“”,$0~“”文件
这将打印任何打开和关闭标记之间的值

awk '/<[^/>].*>/{s=1;next} /<\/[^>].*>/{s=0} s' file
awk'/].*>/{s=1;下一个}/].*>/{s=0}s'文件
但是,不检查它们是否匹配

我相信它可以进一步简化,但这将确保打开和关闭标记匹配(仍然无法处理嵌套标记)


$awk'/].*>{sub(永远不要使用范围表达式,因为它们使琐碎的作业变得最简单,但当问题变得更有趣时,就需要完全重写和/或复制条件。始终使用标志,例如
awk'/start/{f=1}f;/end/{f=0}

在本例中,假设您的输入文件与您提供的示例一样简单且格式良好,因此不需要XML解析器:

awk -v OFS=':' '
    match($0,/^<[^\/>]+>$/) {
        f = 1
        end = "</"substr($0,RSTART+1,RLENGTH-1)
    }
    f {print FILENAME, FNR, $0}
    $0 == end { f = 0 }
' file
file:1:<tag_1>
file:2:This is 1 comment.
file:3:</tag_1>
file:7:<any_tag>
file:8:This is yet another comment.
file:9:</any_tag>
由于您似乎对如何运行它感到困惑:

$ cat file
<tag_1:sub_tag>
This is 1 comment.
</tag_1:sub_tag>

or

<any_tag>
This is yet another comment.
</any_tag>


$find.-type f-exec awk-v OFS=”:“”
$0==end{f=0}
f{打印文件名,FNR,$0}
匹配($0,/^]+>$/){
f=1

end=“我尝试查找。-type f-exec awk'$0~”,$0~“{print FILENAME”:“FNR”:“$0}”{}\;它仍在到处打印。我不熟悉awk。我如何才能让它工作?确保你的
find
找到文件,然后如果你不知道
-exec
语法,只需通过管道到xargs。也就是说,
find…| xargs awk-v…
。当然,最后没有文件名。我尝试了查找。-键入f-exec awk-v tag=“*”$0~”,$0~“{打印文件名”:“FNR”:“$0}”{}\;和find.-type f-exec awk-v tag=“*”'$0~”,$0~“{打印文件名”:“FNR”:“$0}”{}\;但它们都不起作用。@UrsaMajor没有测试用例,不可能说出哪里出了问题!奇怪的是,你在这个问题上投了反对票。考虑到所有的单字符变量(
a,c,s,i,t
?),读起来有点困难虽然没有空白,但最终的脚本将从发布的示例输入中生成所需的输出,并且您已经尽力让OP告诉您它以何种方式不适用于他,以便您可以帮助他找出问题所在(这可能是因为他的输入没有如图所示格式化,或者他没有复制/粘贴您的脚本,而是输入了错误的脚本,或者他使用了非POSIX awk)。我将向上投票以制衡。不要使用
awk
使用可以解析内容的东西。您可以演示一个工作示例吗?这只是一个文件吗?如何递归执行?如何在命令行上使用它?它没有响应。它是一个awk脚本。您可以在stdin或文件上运行它。您可以在一个或多个文件上运行它。UNIX工具递归查找文件是
find
,因此如果您想在find找到的文件上运行awk脚本,那么可以使用finds
-exec
或将其输出到xargs或shell循环。您在命令行上运行它,就像我在命令行上显示它正在运行一样,我不知道除了显示要获取的内容之外,您可能在做什么其效果是,
它没有响应
,但我已将我答案的底部编辑为100%明确。有没有方法执行命令行?对不起,通常我在命令行上有限地使用awk。它是否递归运行并自行搜索子文件夹?我不明白是什么让你困惑。我的答案是awk在命令行上运行我已经告诉过你(你自己也知道这一点,因为它包含在你的问题中),在UNIX中递归查找文件的方法是使用命令
find
。只要用我发布的awk命令替换你问题中的awk命令,工作就完成了。
$find.-type f-exec awk-v of s=':''match($0,/^]+>$/){f=1结束=”
$ awk '/<[^/>].*>/{sub("<","</");t=$0;delete a;c=0;s=1;next}
             t==$0{for(i=1;i<=c;i++)print a[i];delete a;c=s=0;t=""} 
                 s{a[++c]=$0}' file
awk -v OFS=':' '
    match($0,/^<[^\/>]+>$/) {
        f = 1
        end = "</"substr($0,RSTART+1,RLENGTH-1)
    }
    f {print FILENAME, FNR, $0}
    $0 == end { f = 0 }
' file
file:1:<tag_1>
file:2:This is 1 comment.
file:3:</tag_1>
file:7:<any_tag>
file:8:This is yet another comment.
file:9:</any_tag>
awk -v OFS=':' '
    $0 == end { f = 0 }
    f {print FILENAME, FNR, $0}
    match($0,/^<[^\/>]+>$/) {
        f = 1
        end = "</"substr($0,RSTART+1,RLENGTH-1)
    }
' file
file:2:This is 1 comment.
file:8:This is yet another comment.
$ cat file
<tag_1:sub_tag>
This is 1 comment.
</tag_1:sub_tag>

or

<any_tag>
This is yet another comment.
</any_tag>
$ awk -v OFS=':' '
    $0 == end { f = 0 }
    f {print FILENAME, FNR, $0}
    match($0,/^<[^\/>]+>$/) {
        f = 1
        end = "</"substr($0,RSTART+1,RLENGTH-1)
    }
' file
file:2:This is 1 comment.
file:8:This is yet another comment.
$ ls
file

$ cat file
<tag_1:sub_tag>
This is 1 comment.
</tag_1:sub_tag>

or

<any_tag>
This is yet another comment.
</any_tag>
$ find . -type f -exec awk -v OFS=':' '
    $0 == end { f = 0 }
    f {print FILENAME, FNR, $0}
    match($0,/^<[^\/>]+>$/) {
        f = 1
        end = "</"substr($0,RSTART+1,RLENGTH-1)
    }
' {} \;
./file:2:This is 1 comment.
./file:8:This is yet another comment.
$ find . -type f -exec awk -v OFS=':' '$0 == end { f = 0 } f {print FILENAME, FNR, $0} match($0,/^<[^\/>]+>$/) { f = 1; end = "</"substr($0,RSTART+1,RLENGTH-1) }' {} \;
./file:2:This is 1 comment.
./file:8:This is yet another comment.
$ find . -type f -exec awk -v OFS=':' ' match($0,/^<[^\/>]+>$/) { f = 1; end = "</"substr($0,RSTART+1,RLENGTH-1) } f {print FILENAME, FNR, $0} $0 == end { f = 0 } ' {} \;
./file:1:<tag_1:sub_tag>
./file:2:This is 1 comment.
./file:3:</tag_1:sub_tag>
./file:7:<any_tag>
./file:8:This is yet another comment.
./file:9:</any_tag>