在 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
或 inzsh
afterset -o rcquotes
,'s/(Y, d'')/\\opair{Y, d''}/g'
这\
在单打中并不特殊(尽管问题现在转移到如何将'
s 传递给sed
)。- for
find
,-name
通常比测试更便宜,-type
因此最好将其放在第一位(find
尽管有些实现会自行重新排序作为优化)。 - 对于
sed
FreeBSD 以外的实现(也是 Macos 上的实现),必须将备份后缀附加到该-i
选项。在 FreeBSD 和 macos 上, 和 都-i .bak
可以-i.bak
工作,但后者更便携且更面向未来,因为 FreeBSD/macos 将来可能会选择与其他实现保持一致。
另请注意,有很多字符看起来相同,有些字符是不可见的(包括一些控制字符)。例如,您确定Y,
和之间的空格d'
是 ASCII 空格 (U+0020) 而不是不间断空格 (U+00A0) 吗?或者这'
是 ASCII 撇号而不是 U+2019,正确的引用?
在 中vim
,ga
为您提供有关光标下字符的信息。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
实现(包括find
GNU 系统上的 GNU),-name '*.tex'
可能无法匹配以 结尾.tex
但其余部分无法解码为当前语言环境中的字符的文件名。例如,它会跳过$'St\xe9phane'
在使用 UTF-8 作为字符编码的语言环境中调用的文件,因为单独的 0xe9 字节无法解码为字符。在命令前面加上前缀LC_ALL=C
可以解决这个问题。