Perlとsedで印刷できない文字を置き換える

Perlとsedで印刷できない文字を置き換える

ファイルから印刷できない一部の文字を空白に置き換える必要があります。

0x00特に(TAB)、(改行)、(CR)0x1F以外のすべての文字0x090x0A0x0D

これまでは役割だけを変えればいいです0x00。以前のOSはAIX(GNUコマンドなし)だったので利用できませんでしたsed(まあ、利用可能でしたが、いくつかの制限がありました)。だから私は次のコマンドを見つけましたが、perl期待どおりに動作します。

perl -p -e 's/\x0/ /g' $FILE_IN > $FILE_OUT 

sed今私はLinuxを使用しているので、コマンドを使用できるようにしたいです。

私の質問:

  • このコマンドはこれらの文字を置き換えるのに適していますか?これを試しましたが、うまくいくようですが、次のことを確認したいと思います。

    perl -p -e 's/[\x00-\x08\x0B\x0C\x0E-\x1F]/ /g' $FILE_IN > $FILE_OUT  
    
  • 私はperl -pそれがうまくいくと思いますsed。それでは、前のコマンドは機能しますが(少なくとも失敗せず)、次のコマンドが機能しないのはなぜですか?

    sed -e 's/[\x00-\x08\x0B\x0C\x0E-\x1F]/ /g' $FILE_IN > $FILE_OUT   
    

    それは私に言う:

    sed: -e 式 #1、文字 34: 無効なソート文字

ベストアンサー1

一般的な作業は次のとおりですtr

LC_ALL=C tr '\0-\10\13\14\16-\37' '[ *]' < in > out

sedあなたの場合、範囲はあなたのロケールで理解されていないので動作しません。文字の代わりにバイト値を使用し、順序がそのバイトの数値に基づいている場合、最良のオプションは次のとおりです。C ロケールの使用。あなたのコードはLC_ALL=CGNUと一緒に使用することができますが、ここでsed使用するのはsed少しperl過剰です(そしてメソッドは\xXX実装面では移植性がありませんが、sedこのtrメソッドはPOSIXです)。

地域のアイデアを信頼することもできます。印刷可能文字は次のとおりです。

tr -c '[:print:]\t\r\n' '[ *]'

ただし、GNU tr(通常はLinuxベースのシステムに見られる)では、文字が単一バイト(通常はUTF-8ではない)のロケールでのみ機能します。

Cロケールでは、DEL(0x7f)と上記のすべてのバイト値(ASCII以外)も除外されます。

UTF-8ロケールでは、GNUが持っている問題にsed遭遇しないGNUを使用できます。tr

sed 's/[^[:print:]\r\t]/ /g' < in > out

(これは標準で\rはなく、\tGNUは環境にある場合はそれを認識しませんsed(バックスラッシュで処理し、rとtはPOSIXで要求されるセットの一部です)。POSIXLY_CORRECT

ただし、有効な文字(存在する場合)を形成しないバイトは変換されません。

おすすめ記事