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

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

答え2

libnotifyを介して通知を送信しようとしていますが、コンテンツに印刷できない文字を含めることができます。既存のソリューションは私にとってうまくいきません(tr有効な文字ホワイトリストを使用しますが、マルチバイト文字を削除します)。

これは有効で、両方を通過します。

関連情報