
我試圖使用 sed 文件來預處理文件,但 sed 的輸出似乎改變了格式。我該如何避免呢?
file A.txt
A.txt UTF-8 Unicode English text, with very long lines
sed -f process.sed < A.txt > B.txt
head -2 process.sed
#!/bin/sed -f
s/[‘’"“”•·・、。《》™®\.★☆]\\[a-z\-]\+ //g
file B.txt
Non-ISO extended-ASCII English text, with very long lines, with LF, NEL line terminators
因為B.txt不是UTF-8編碼的,所以我無法進行以下處理。
vim B.txt
è·¯æ<98><93>æ<96>¯ Âç½<97>å¾·é<87><8c>æ ¼æ<96>¯ //è·¯æ<98><93>æ<96>¯Â·ç½<97>å¾·é<87><8c>æ ¼æ<96>¯ ]
答案1
問題是 sed 的正規表示式引擎不會將您的輸入檔案或您的[…]
匹配視為 Unicode 字元清單;相反,它將每個位元組視為多個獨立的位元組。例如,它•
視為三個位元組\xe2 \x80 \xa2
並嘗試將每個位元組分別與[ \xe2 \x80 \x98 \xe2 \x80 \x99 \x22 \xe2 \x80 ... ]
.
因此,在您在帖子中顯示的範例中,正規表示式僅匹配並刪除每個標點符號的最後一個字節,但將其他 2 個位元組保留在那裡。這就是為什麼給您無效(非 UTF-8)輸出檔案的原因。
使用 GNU sed(在 4.5 上測試),可以透過確保系統區域設定($LANG 或至少 $LC_CTYPE 環境變數)設定為 UTF-8 相容的語言環境。例如:
$ 導出 LANG='C' $ echo ''測試'“測試”'| sed 's/[“”•]/X/g' XX�測試XX�XXX測驗XXX $ echo '•_test' | sed 's/[•‡]_/X_/' ��X_測試 $ 導出 LANG='en_US.UTF-8' $ echo ''測試'“測試”'| sed 's/[“”•]/X/g' '測試'XtestX $ echo '•_test' | sed 's/[•‡]_/X_/' X_測試
(區域設定語言並不重要。任何UTF-8 語言環境將會運作。
如果這對您不起作用,請[…]
完全避免並使用\(…\|…\|…\)
(或(…|…|…)
在 sed -r 中),這是一個多字元替代方案,無論這些字元最終如何解釋,它都會起作用。
$ 導出 LANG='C' $ echo ''測試'“測試”'| sed 's/\(“\|”\|•\)/X/g' '測試'XtestX $ echo '•_test' | sed 's/\(•\|‡\)_/X_/' X_測試