如何在 sed 内的 bash 执行中保留双引号

如何在 sed 内的 bash 执行中保留双引号

我有一个包含很多这样的行的日志文件:

2021/09/03-13:11:05;QUEUE.INBOUND;4;ID:myhost.mydomain.net-7756-1629822315072-199:973:1:1:1;MISC;"<?xml version="1.0" encoding="UTF-8"?> <RootElement xmlns="urn:namespace:entity/1" tstamp="2021-02-29T12:11:00Z" object="urn:domain:entity:ID1234"><Active lang="en" value="true">active</Active><Name lang="en">Some Name</Name><ShortName lang="en">shortname</ShortName><Phone number="+416458838829" lang="en">+416458838829</Phone><Email>[email protected]</Email><Longitude>7.043786</Longitude><Latitude>47.239036</Latitude></RootElement>"

(XML 比这个大,但这只是一个示例。)

我的目标是将每一行中的每个 XML 提取到一个专用文件中。如果日志包含 10 行,则将创建 10 个文件。

我是这样开始的:

more mylogfile.txt | sed -r 's!^.*\s(<RootElement.*\sobject="urn:domain:entity:([A-z0-9]*)"><Active.*</RootElement>).*!echo "\1" | xmlstarlet fo > "\2.xml"!e; d'

这个想法是提取对象 urn 中的 ID 并将其用作文件名(id 在文件中是唯一的)。

问题:

单独执行“echo”命令时

more mylogfile.txt | sed -r 's!^.*\s(<RootElement.*\sobject="urn:domain:entity:([A-z0-9]*)"><Active.*</RootElement>).*!echo "\1"!e; d'

我注意到 XML 中的双引号刚刚被擦除,并且xmlstarlet命令(在第一次尝试中)只会出错。

Active 元素的示例将变为:

<Active lang=en value=true>active</Active>

sed我知道在和中执行 bash 命令时语法有一些技巧echo,但我尝试了几种不同的语法(例如删除 \1 周围的“”、使用printf、改为使用xargsexternalsed等),但没有一个成功。

我使用的是 Ubuntu 发行版 18.04(Windows 下的 WSL 1)。

echo或“ ”命令中是否有任何选项sed s!...!...!e可以改善此问题?

(如果你找到更有效的方法,我也很开放)

答案1

您需要先使用 转义引号s/"/\\"/g。这样可以防止它们被吃掉echo

然后记得调整您的搜索模式。您需要匹配\"而不是",并且反斜杠需要转义,因此它需要位于\\"搜索模式中:

sed -E 's/"/\\"/g;s!^.*\s(<RootElement.*\sobject=\\"urn:domain:entity:([A-Za-z0-9]*)\\"><Active.*</RootElement>).*!echo "\1"!e;d'

相关内容