如何搜寻和替换sed和awk(和perl)中的任意文字字符串 [英] How to search & replace arbitrary literal strings in sed and awk (and perl)

查看:114
本文介绍了如何搜寻和替换sed和awk(和perl)中的任意文字字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们在文件中有一些任意文字,我们需要将其替换为其他文字.

Say we have some arbitrary literals in a file that we need to replace with some other literal.

通常,我们只需要获取 sed (1)或 awk (1)并编写如下代码:

Normally, we'd just reach for sed(1) or awk(1) and code something like:

sed "s/$target/$replacement/g" file.txt

但是,如果$ target和/或$ replacement可能包含对 sed (1)敏感的字符,例如正则表达式.您可以逃脱它们,但假设您不知道它们是什么-它们是任意的,好吗?您需要编写一些代码来转义所有可能的敏感字符-包括'/'分隔符.例如

But what if the $target and/or $replacement could contain characters that are sensitive to sed(1) such as regular expressions. You could escape them but suppose you don't know what they are - they are arbitrary, ok? You'd need to code up something to escape all possible sensitive characters - including the '/' separator. eg

t=$( echo "$target" | sed 's/\./\\./g; s/\*/\\*/g; s/\[/\\[/g; ...' ) # arghhh!

对于这样一个简单的问题,这很尴尬.

That's pretty awkward for such a simple problem.

perl (1)带有\ Q ... \ E引号,但即使那样也无法应付$target中的'/'分隔符.

perl(1) has \Q ... \E quotes but even that can't cope with the '/' separator in $target.

perl -pe "s/\Q$target\E/$replacement/g" file.txt

我刚刚发布了答案!!所以我真正的问题是,是否有更好的方法在sed/awk/perl中进行文字替换?"

I just posted an answer!! So my real question is, "is there a better way to do literal replacements in sed/awk/perl?"

如果没有,我将其留在这里,以防它有用.

If not, I'll leave this here in case it comes in useful.

推荐答案

再次与我联系!

这是使用 xxd (1)的一种更简单的方法:

Here's a simpler way using xxd(1):

t=$( echo -n "$target" | xxd -p | tr -d '\n')
r=$( echo -n "$replacement" | xxd -p | tr -d '\n')
xxd -p file.txt | sed "s/$t/$r/g" | xxd -p -r

...所以我们用 xxd (1)对原始文本进行十六进制编码,并使用十六进制编码的搜索字符串进行搜索替换.最后,我们对结果进行十六进制解码.

... so we're hex-encoding the original text with xxd(1) and doing search-replacement using hex-encoded search strings. Finally we hex-decode the result.

我忘了从xxd输出(| tr -d '\n')中删除\n,以便模式可以跨越xxd的60列输出.当然,这取决于GNU sed在很长的行(仅受内存限制)上进行操作的能力.

I forgot to remove \n from the xxd output (| tr -d '\n') so that patterns can span the 60-column output of xxd. Of course, this relies on GNU sed's ability to operate on very long lines (limited only by memory).

这也适用于多行目标,例如

this also works on multi-line targets eg

target = $'foo \ nbar' 替换= $'bar \ nfoo'

target=$'foo\nbar' replacement=$'bar\nfoo'

这篇关于如何搜寻和替换sed和awk(和perl)中的任意文字字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆