Sed
如何用’遞歸替換字元串?
在 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
我看到的文件,實際上並不需要轉義),但這並不能解決問題。
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 可能會選擇在未來與其他實現保持一致。還要注意有很多看起來相同的字元和一些不可見的字元(包括一些控製字元)。例如,您確定 and 之間的空格
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
實現,包括 GNUfind
系統上的 GNU,-name '*.tex'
可能無法匹配以結尾.tex
但其餘部分無法解碼為目前語言環境中的字元的文件名。例如,它會跳過$'St\xe9phane'
在使用 UTF-8 作為其字元編碼的語言環境中呼叫的文件,因為單獨的 0xe9 字節不能被解碼為字元。為命令加上前綴LC_ALL=C
可以解決這個問題。