如何用 ' 递归替换字符串?

如何用 ' 递归替换字符串?

在 macOS 下的 zsh 终端窗口中,我尝试以递归方式替换当前目录中开始的所有文件的(Y, d')所有实例\opair{Y, d'}.tex

以下似乎什么也没做:

find . -type f -name "*.tex" -print0 | xargs -0 sed -i '.bak' -e "s/(Y, d')/\\opair{Y, d'}/g"

我该如何解决?

我确实尝试过转义'(根据sed我见过的文档,实际上并不需要转义),但这并不能解决问题。

答案1

find . -name '*.tex' -type f -exec \
  sed -i.bak -e "s/(Y, d')/\\\\opair{Y, d'}/g" {} +
  • 你有X而不是Y
  • xargs当您可以使用标准-exec cmd {} +语法时,不需要, 。
  • \需要对 shell 进行转义(双引号内仍然特殊)和sed.或者,您可以执行's/(Y, d'\'')/\\opair{Y, d'\''}/g'or inrc或 in zshafter set -o rcquotes's/(Y, d'')/\\opair{Y, d''}/g'\在单打中并不特殊(尽管问题现在转移到如何将's 传递给sed)。
  • for find,-name通常比测试更便宜,-type因此最好将其放在第一位(find尽管有些实现会自行重新排序作为优化)。
  • 对于sedFreeBSD 以外的实现(也是 Macos 上的实现),必须将备份后缀附加到该-i选项。在 FreeBSD 和 macos 上, 和 都-i .bak可以-i.bak工作,但后者更便携且更面向未来,因为 FreeBSD/macos 将来可能会选择与其他实现保持一致。

另请注意,有很多字符看起来相同,有些字符是不可见的(包括一些控制字符)。例如,您确定Y,和之间的空格d'是 ASCII 空格 (U+0020) 而不是不间断空格 (U+00A0) 吗?或者这'是 ASCII 撇号而不是 U+2019,正确的引用?

在 中vimga为您提供有关光标下字符的信息。uconv -x name < file为您提供输入中每个字符的名称。

reveal() {
  perl -Mcharnames=full -Mopen=locale -pe 's{[^\t\n -~]}{
    sprintf "<U+%04X %s>", ord($&), charnames::viacode(ord($&))}ge' "$@"
}

可以用来揭示(例如)除空格、制表符、换行符和 ASCII 可打印字符以外的字符<U+3000 IDEOGRAPHIC SPACE>St<U+00E9 LATIN SMALL LETTER E WITH ACUTE>phane Stéphane

另请注意,对于某些find实现(包括findGNU 系统上的 GNU),-name '*.tex'可能无法匹配以 结尾.tex但其余部分无法解码为当前语言环境中的字符的文件名。例如,它会跳过$'St\xe9phane'在使用 UTF-8 作为字符编码的语言环境中调用的文件,因为单独的 0xe9 字节无法解码为字符。在命令前面加上前缀LC_ALL=C可以解决这个问题。

相关内容