sed - 匹配模式的反向引用不起作用

问题描述 投票:0回答:2

我需要在文件(xml)中找到这种格式的日期

2021-06-25T21:17:51Z
并将其替换为这种格式
2021-06-25T21:17:51.001Z

我考虑过将正则表达式与

sed
一起使用,但反向引用不起作用。

1.xml 可能看起来像这样,但这些文件中有更多字段,并且我得到的字段已经正确。

<Doc>
   <PUB_DATE>2021-06-25T21:17:51Z</PUB_DATE><!-- to change -->
   <DATE_COLLECT_100>2021-06-25T21:17:51Z</DATE_COLLECT_100><!-- to change -->

   <DATE_CREATION>2021-06-25T21:17:51.001Z</DATE_CREATION><!-- keep it like this -->
</Doc>

期望的输出是

<Doc>
   <PUB_DATE>2021-06-25T21:17:51.001Z</PUB_DATE><!-- to change -->
   <DATE_COLLECT_100>2021-06-25T21:17:51.001Z</DATE_COLLECT_100><!-- to change -->

   <DATE_CREATION>2021-06-25T21:17:51.001Z</DATE_CREATION><!-- keep it like this -->
</Doc>

这是我的

sed

$ sed -Ee 's#<(PUB_DATE|DATE_COLLECT_100){1}>([[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2})Z</\1>#<\1>\2.001Z</\1>#' 1.xml

正则表达式似乎在 regex101

中没问题

这里是用 https://regexper.com 制作的表示 representation of the regexp

在搜索部分使用反向引用时,sed 中是否允许反向引用? 我是不是错过了一些关于

sed
的事情? 有bug吗?

Sed 版本:嗯...我不知道,

sed --version
sed -v
man sed
没有给出。我在 OSX 上。

regex macos sed backreference
2个回答
6
投票

BSD 或 OSX sed 不支持正则表达式模式中的反向引用

\1

您的选择是

perl
:

perl -pe 's#<(PUB_DATE|DATE_COLLECT_100)>(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})Z</\1>#<\1>\2.001Z</\1>#' 1.xml

或者使用

gnu sed
安装程序安装
home brew
,然后使用:

gsed -E 's#<(PUB_DATE|DATE_COLLECT_100)>([[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2})Z</\1>#<\1>\2.001Z</\1>#' 1.xml

0
投票

在每个 Unix 机器上的任何 shell 中使用任何 awk 来替代正则表达式中的反向引用:

$ awk '
    match($0,/<(PUB_DATE|DATE_COLLECT_100)>/) && index($0,"</"substr($0,RSTART+1,RLENGTH-1)) {
        sub(/:[0-9]+Z/,":001Z")
    }
1' file
<Doc>
   <PUB_DATE>2021-06-25T21:17:001Z</PUB_DATE><!-- to change -->
   <DATE_COLLECT_100>2021-06-25T21:17:001Z</DATE_COLLECT_100><!-- to change -->

   <DATE_CREATION>2021-06-25T21:17:51.001Z</DATE_CREATION><!-- keep it like this -->
</Doc>
© www.soinside.com 2019 - 2024. All rights reserved.