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

查看:8
本文介绍了如何搜索 &替换 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$targetE/$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 '
')
r=$( echo -n "$replacement" | xxd -p | tr -d '
')
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 ' ') 中删除 以便模式可以跨越 60 列输出xxd.当然,这依赖于 GNU sed 对非常长的行进行操作的能力(仅受内存限制).

I forgot to remove from the xxd output (| tr -d ' ') 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 bar'替换=$'bar foo'

target=$'foo bar' replacement=$'bar foo'

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

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