我很高兴该选项grep
支持 Perl 兼容正则表达式-P
。
sed
该工具没有此功能的原因是什么?
答案1
解决方法:
您可以使用 Pathological Eclectic Rubbish Lister:
perl -pe 's/../../g' file
或内联替换:
perl -i -pe 's/../../g' file
这适用于我使用的情况sed
。如果事情变得更加复杂,我会编写一个小的python脚本。
顺便说一句,我换到了无需 Shell 脚本
答案2
对于 GNU Sed 来说,陈述理由似乎
我担心它会落入其中一个“裂缝”......虽然从当时的说法来看,部分工作已经完成,看起来就像是文档和包装的问题......(不过,我承认,在计算机科学领域,最后 10% 的工作往往要花费 90% 的时间......
看GNU 错误报告日志 - #22801 已提交变更的状态:升级“sed”RE 以包含 perlRE 语法- 或搜索sed-devel 档案如果您想了解更多详细信息,请搜索“PCRE”。
不要忘记,您可以将perl
它用于许多可能想要使用 PCRE 的简单的单行代码中sed
。
答案3
随着我的替换需求变得越来越复杂,使用perl -pe
变得比 更可取sed -e
。特别是,能够使用perl
字符类和量词比我需要克服的困难更简洁sed
。
journalctl -u auditd -S 'yesterday' |\
perl -pe 's/^(\w{3} \d{2} \d{2}:\d{2}:\d{2}) ([\w-]+) audispd/$1 generic-hostname audispd/;
s/node=[\w-]+/node=generic-hostname/;'
对比
journalctl -u auditd -S "yesterday" |\
sed -e 's/^\([[:alpha:]]\{3\} [[:digit:]]\{2\} [[:digit:]]\{2\}:[[:digit:]]\{2\}:[[:digit:]]\{2\}\) \([[:alpha:]-]\+\) audispd/\1 generic-hostname audispd/;
s/node=\([[:alpha:]-]\+\) /node=generic-hostname /;'
我可以使用[0-9]
而不是[[:digit:]]
和[A-Za-z]
而不是[[:alpha:]]
,但是 a) 它们都比 perl 等效项长,并且 b)[A-Za-z]
将匹配非 ASCII 字符,就像 perl 等效项一样。
bosses-r-dum> echo 'å' | sed -e 's/[A-Za-z]/X/'
å
bosses-r-dum> echo 'å' | perl -CS -pe 's/\w/X/'
X
bosses-r-dum>
如果您必须处理 unicode,那么能够添加标志并让事情“正常工作”非常方便。我倾向于有机地发展我的正则表达式,因此对“简单”和“复杂”正则表达式使用相同的工具是有意义的,因为如果/当需求发生变化并且我不需要进行任何工具更改(将所有[x]\{#\}
实例更改为[x]{#}
等),我的“简单”正则表达式可以轻松变成“复杂”正则表达式。
答案4
我个人发现用 Python 做这件事比用 Perl 或 Sed 做起来更容易。
cat file \
| python3 -c 'import sys, re; s = sys.stdin.read(); s=re.sub(r"regex", "replace string", s); print(s);' \
| sudo tee file
完整示例
# add quay and docker registries to approved cri-o registries
cat /etc/crio/crio.conf \
| python3 -c 'import sys, re; s = sys.stdin.read(); s=re.sub(r"#registries\s+\=\s+\[\n#\s+\]", "registries = [\"docker.io\",\"quay.io\"]", s); print(s);' \
| sudo tee /etc/crio/crio.conf