如何避免Sed改變文件格式?

如何避免Sed改變文件格式?

我試圖使用 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_測試

相關內容