1つのファイルからすべての非ASCII文字を削除するにはどうすればよいですか?これを実行する特定のコマンドはありますか?
grep --colour='auto' -P -n'[^\x00-\x7]' /usr/local/...
これでワークフロー内のキャラクターが見つかると思いますが、問題のキャラクターのインスタンスをすべて削除するにはどうすればよいですか?
ASCII文字は 〜177(8進数)の範囲の文字を含む です。
ファイル内でこの範囲外の文字を削除するには、次を使用します。
LC_ALL=C tr -dc '\0-\177' <file >newfile
tr
コマンドは、単一の文字で機能するユーティリティです 、他の単一の文字で置き換える(文字変換)、削除する、または同じ文字のランを単一の文字に圧縮する。
上記のコマンドはfile
から読み取り、変更されたコンテンツをnewfile
に書き込みます。 -d
オプションをtr
に指定すると、ユーティリティは文字を文字変換する代わりに削除し、-c
は、(内部ではなく)指定された間隔の外側の文字を考慮します。
LC_ALL=C
は、すべてのバイト値が有効な文字であることを確認します。これがないと、一部のtr
実装は、ロケールの文字エンコーディングで有効な文字を形成しないバイトシーケンスを検出した場合に中止されます。
元のファイルを変更されたファイルで置き換えるには、次を使用します
LC_ALL=C tr -dc '\0-\177' <file >newfile &&
mv newfile file
これにより、tr
が正常に完了した後に、新しいファイルの名前が古いファイルの名前に変更されます。 tr
が正常に完了しない場合、元のファイルを読み取れなかったか、新しいファイルに書き込めなかったため、元のファイルは変更されません。
または、元のファイルのメタデータ(権限など)をできる限り保存するには、次のコマンドを使用します。
cp file tmpfile &&
LC_ALL=C tr -dc '\0-\177' <tmpfile >file &&
rm tmpfile
Perl
Perl -pi -e 's/[^[:ascii:]]//g'
必要なのが正規表現だけの場合:[\x00-\x7F]
いくつかのユーティリティに適用できます:
<file LC_ALL=C sed 's/[^\o0-\o177]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^\0-\177]/,"");print}'
<file Perl -pe 's/[^[:ascii:]]//g;'
<file LC_ALL=C tr -dc '\0-\177'
Unixで定義されているsed、awk、Perlが「テキストファイル」を期待していることを理解してください。この場合、すべてうまくいきます。しかし、具体的には、awkは末尾に新しい行を追加します(ソースファイルに存在していたかどうかに関係なく)(printfを使用すると、入力のすべての改行が削除されます)。 trは、あらゆる種類のファイルで機能するように設計されています。ただし、NUL(\0
)は POSIXテキストファイル の有効な文字ではないため、避ける必要があります。
行にNUL文字が含まれていません...
実際、多くの制御文字は、特定の条件下で他の問題を生成します。
それで、おそらくあなたは[\x07-\x0d\x20-\x7e]
<file LC_ALL=C sed 's/[^\o007-\o015\o040-\o176]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^\0-\15\40-\176]/,"");print}'
<file Perl -pe 's/[^\x{7}-\x{d}\x{20}-\x{7e}]//g;'
<file LC_ALL=C tr -dc '\7-\15\40-\176'
範囲7-13(10進数)は\a\b\t\n\v\f\r
(順番に)。
同様の(おそらくよりポータブルな)範囲は[^[:space:][:print:]] (similar because it doesn't include
\a\b`-ベルとバックスペース-)。
<file LC_ALL=C sed 's/[^[:space:][:print:]]//g' # GNU sed without POSIXLY_CORRECT
<file LC_ALL=C awk '{gsub(/[^[:space:][:print:]]/,"");print}'
<file Perl -pe 's/[^[:space:][:print:]]//g;'
<file LC_ALL=C tr -dc '[:space:][:print:]'