是否可以从 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 ...
'
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 ...
'