use*_*118 2 linux sed awk pattern-matching
我有一个像下面这样的文件
<g> Good wheatear </g> other parts of line
<g> The farm land is to be sold </g> other parts of line
<g> knock knock </g> other parts of line
Run Code Online (Sandbox Code Playgroud)
我希望我的输出是这样的:
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
Run Code Online (Sandbox Code Playgroud)
即打印 <g> 和 </g> 标签之间的内容,包括标签
我试过这个命令:
awk '/<s>/, /<\/s>/' trsTest.txt
但它打印了整行。
如何打印标签之间的内容?
有了awk它可能是:
$ awk -v FS="</?g>" '{print $2}' trsTest.txt
Good wheatear
The farm land is to be sold
knock knock
Run Code Online (Sandbox Code Playgroud)
或者,如果您想保留标签:
$ awk -v FS="</g> " '{print $1 FS}' trsTest.txt
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
Run Code Online (Sandbox Code Playgroud)
您可以简单地使用 GNU grep 并仅打印行的匹配部分 ( -o):
grep -o '<g>.*<\/g>' trsTest.txt
Run Code Online (Sandbox Code Playgroud)
模式需要在单引号之间,以防止外壳扩展字符(如*)
第一个命令将产生:
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
Run Code Online (Sandbox Code Playgroud)
如果你不想包含标签,那么你可以这样做:
sed 's/.*<g>\(.*\)<\/g>.*/\1/' trsTest.txt
Run Code Online (Sandbox Code Playgroud)
它的工作方式如下:
<g>标签在内的所有内容\(和之间的东西\)<\g>标记之后的任何内容与行尾匹配\1第二个命令将产生:
Good wheatear
The farm land is to be sold
knock knock
Run Code Online (Sandbox Code Playgroud)
如果这是 XML,您可以使用 XML 解析器,例如xmlstarlet. (如果它是 HTML,您仍然可以使用,xmlstarlet但您必须警告它结构可能已损坏。)
我添加了一个边界<root/>元素来使输入合法的 XML:
<root>
<g> Good wheatear </g> other parts of line
<g> The farm land is to be sold </g> other parts of line
<g> knock knock </g> other parts of line
</root>
Run Code Online (Sandbox Code Playgroud)
然后挑选</g>元素和值的命令是
xmlstarlet sel --template --match '//g' --copy-of '.' --nl file.xml
Run Code Online (Sandbox Code Playgroud)
输出
<g> Good wheatear </g>
<g> The farm land is to be sold </g>
<g> knock knock </g>
Run Code Online (Sandbox Code Playgroud)
相xmlstarlet对于通用文本解析工具(例如sed或grep)的优势在于它可以理解 XML 结构,因此如果输入文件略有更改,同时仍然保持有效的 XML,xmlstarlet仍将能够解析它。