如何在文件中搜索字符串然后将其用作变量?

如何在文件中搜索字符串然后将其用作变量?

我有一个如下所示的 XML 文件:

<id>456</id>

<root>
<value>1</value>
<intNum>2</intNum>
</root>

<root>
<eulav>1</eulav>
<muNtni>2</muNtni>
</root>   

我想记住<id>456</id>然后这样做:

sed 's/\<root\>/\
\<root\> 
$herecomestheid

基本上,它的作用就是替换<root><root>\n<id>456</id>.\n在这种情况下意味着换行。我已经知道了,但我遇到的问题是记住<id>456</id>并保留它以供以后使用。

我尝试了这个(这显然不起作用):

 sed -i '' 's/\<root\>/\
 \<root\>\
 \<id\>.\<\/id\>/g'

我尝试做这样的事情:

cat file.xml | grep '\<id\>*\<\/id\>'

并尝试将 grep 输出放入变量中。这显然也不起作用。

编辑: <id>*</id>应该在根目录下。

答案1

将 XML 作为文本处理通常不是一个可靠的解决方案,但如果您坚持这样做,那么您也许可以使用 sed保留空间 例如

sed -e '/<id>[0-9]*<\/id>/h' -e '/<root>/{x;p;x;}' file.xml

答案2

sed -e :b -e '$!{N;\|<id>.*\n<root>|!bb
};do what ever you want to do with all of those lines now....'

我同意 Steeldriver 的观点,认为holdspace 可能是最好的选择,但还有其他选择。有时我们懒得管理两个缓冲区 - 或者,这通常是我的问题 - 我们已经管理两个缓冲区。上面的代码片段在模式空间中堆叠行。只要总是出现在<id>标签之间,在移动到第 2 行之前,它总是会用所需的数据块递归地填充模式空间 -也就是说,只要缓冲区不同时崩溃,它就会这样做 - 但现在这是一件相当困难的事情

另外,回到h旧的空间问题,电子x改变确实如此交换 h旧的和图案的空间。使用它一次会将模式缓冲区渲染为h旧缓冲区,反之亦然。这种效应在线路周期中仍然存在。我所做的通常是读取文件,直到到达起始行,执行初步编辑,然后交换并保持H旧状态,直到得到另一个。当我的脚本交换回来时,它会落后一个块 - 在我打开的最后一个标记处,加上H同时的所有字段。这是一种简单的方法,可以在必要时仅缓冲必要的量。

因此,实现您想要的循环的另一种方法是:

sed -e '/<id>/h;//!H;/<root>/!{$!d' -e '};x...'

从那时起,您的模式空间就是H旧空间,反之亦然。h旧遗嘱覆盖 h每当使用旧空间时,它都会与当前模式空间一起使用 - 因此上面的示例<id>每次都会用一行开始一个新的缓冲区。!H 追加H旧空间的所有中间行均跟随一个\newline 字符。一旦当前行安全地进入并开始下一个行循环,就会删除不是最后一行$!d的每一行上的模式空间,因此更改仅发生在整个块正在等待您的匹配上。!$Hx<root>

请记住,在您的最后块,您的标记可能是最后一行,以防它与<root>匹配项不同。

但...

根据您的编辑,我不认为您有任何理由无法逃脱:

sed '/<id>/h;//d;\|</root>|G
' <<\INPUT
unimportant 1
<id> number 1 </id>
<root> sub text
more text
 more text
</root>
<root> sub text as well
and more text
and more text
</root>
unimportant 2
<id> number 2 </id>
<root> sub text
more text
more text
</root>
<root> sub text
and more text
and more text
</root>
INPUT

<id>线路是h字段(再次:覆盖h旧空间)然后d从输出中删除。当</root>发生匹配时,在行周期末尾自动打印结果之前,sed G将旧空间附加到模式空间,如下所示:h

unimportant 1
<root> sub text 
more text
 more text
</root>
<id> number 1 </id>
<root> sub text as well
and more text
and more text
</root>
<id> number 1 </id>
unimportant 2
<root> sub text
more text
more text
</root>
<id> number 2 </id>
<root> sub text
and more text
and more text
</root>
<id> number 2 </id>

答案3

使用的解决方案awk

awk '/<id>/{id=$0}/<root>/{print id}1' file.xml

如果您不想打印该<id>行,可以通过添加 来跳过该行next

awk '/<id>/{id=$0;next}/<root>/{print id}1' file.xml

相关内容