是否可以从 sed 内部传递对函数的反向引用?

Is it possible to pass a backreference to a function from inside sed?

TL;DR 这是不可能的,因为“命令替换中的反向引用不是也不会被 sed 解析,而是在 运行 sed 之前被 shell 解析”(见下面的答案)。

我想用大文本文件 (>50MB) 中的相应字符替换国际音标的 unicode 值。

我的test.txt输入示例:

<CHARSET c="T">02C8;</CHARSET>ku:p<CHARSET c="T">0252;</CHARSET>n] noun<BR>

预期结果:

<CHARSET c="T">ˈ</CHARSET>ku:p<CHARSET c="T">ɒ</CHARSET>n] noun<BR>

我可以使用此命令转换给定的 unicode(例如):

echo -e "\u02C8"

但是我的 sed 命令中的转义失败了。我想到了从 here 创建一个函数,像这样:

codeToChar() { $( echo -e "\u"); }
sed -r -i 's#(<CHARSET c="T">)(....)#'"$(codeToChar \2)"'#g' test.txt

但似乎“\2”反向引用没有传递给函数:

codeToChar() { $( echo -e "\u"); }
sed -r -i 's#(<CHARSET c="T">)(....)#'"$(codeToChar \2)"'#g' test.txt
++ codeToChar ''
+++ echo -e '\u'
++ '\u'
./replace.sh: line 2: \u: command not found
+ sed -r -i 's#(<CHARSET c="T">)(....)##g' test.tx

How to properly escape a backreference in sed to pass it to a function?

提供的代码正确处理了反向引用。命令替换中的反向引用不是也不会被 sed 解析,而是在 运行 sed 之前被 shell 解析。程序的参数必须在 运行 程序之前展开。

您可能会使用 sed 的 GNU 扩展 - e 标志到 s 命令,通过 /bin/sh 解释执行替换模式。非常不鼓励使用此标志并且很难使用,因为很难确定正确的引号和转义 - 它在非常简单的情况下“有效”。因为输入字符串有 ; < >" 特殊 shell 字符我怀疑这是可能的。

我建议选择一种成熟的编程语言,例如 python、perl 或其他语言来解决您的任务。 sed 不是根据文件内容动态执行操作的实用程序,它是一个简单的流替换实用程序。

sed 中,可以构建要替换的静态字符串列表,如下所示:

sed -r '
     s/(<CHARSET c="T">)02C8/'"$(echo -e "\u02C8")"/
     s/(<CHARSET c="T">)0252/'"$(echo -e "\u0252")"/
     .... one s/// command for each character to replace ...
'