私は非常に大きなテキストファイルから外国語や他のキーボード以外の文字を削除するためにSEDコマンドを使用しています。
例:
sed 's/[^a-zA-Z0-9]//g'
上記のコマンドは、私が望むものに近い英数字のみを含むすべての行を保持します。問題は、!@#$%などの一般的な記号を含む行も削除することです。私はそれらを大事にしたい。 !-)のような金塊のコマンドを検索してみました。しかし、似たようなものが見つかりません。
それでは、リストでアラビア語、ロシア語、および入力できない文字をフィルタリングする方法は? (理想的にはキャラクターだけに核爆弾を撃たくしたくなく、キャラクターが見つかった行全体に核爆弾を撃ちたいです。)
答え1
Kusalanandaのようなクラスを使用することに加えて、Unicodeに基づいて独自の範囲を作成できます。確認するこれはユニコールドテーブルを意味します。お気に入りのキャラクターを見つけてください。 PCREの場合、「標準」文字+ TABの可能な方法は次のとおりです。
grep -P '^[\x{0020}-\x{007e}\x{0008}]{1,}$' file
\x{000A}
grep
1行あたりの機能(標準モード)のため、改行文字は制御文字として含まれません。 MSスタイルの改行文字が影響を受けて\x{000d}\x{000a}
改行文字に使用されることを検討してください!
答え2
テキストから非ASCII文字を削除するには、tr
次の方法を使用することをお勧めします。
LC_ALL=C tr -d -c '[:print:][:cntrl:]' <file.in >file.out
2つのPOSIX文字クラスは[:print:]
一緒に[:cntrl:]
ASCII範囲内のすべての文字をカバーするため、これを補完する、つまりすべての非ASCII文字を考慮する必要が-c
あります。tr
私たちはこの補足文字を削除する-d
ように依頼します。tr
文字クラスがASCII範囲32から126の文字のみを一致するように(または)LC_ALL
に設定しました。それ以外の場合は、ロケールの印刷可能文字と一致する可能性があります(例:)。このクラスは、0〜31および127の範囲の文字と一致します。を使用すると、これら2つのクラスにはASCII文字0〜127が含まれます。C
POSIX
[:print:]
ä
[:cntrl:]
LC_ALL=C
非ASCII文字を含む行全体を削除するには:
LC_ALL=C grep -v '[^[:print:][:cntrl:]]' <file.in >file.out
この式は、[^[:print:][:cntrl:]]
ASCIIではなく単一文字と一致します。-v
クエリを使用してgrep
すべての行を抽出します。いいえASCII以外の文字を含まない行を抽出するこの式と一致します。
これら2つのコマンドは、以下を使用して実行することもできますsed
。
ASCII以外の文字を削除します。
LC_ALL=C sed 's/[^[:print:][:cntrl:]]//g' <file.in >file.out
ASCII以外の文字を含む行を削除します。
LC_ALL=C sed '/[^[:print:][:cntrl:]]/d' <file.in >file.out
Stéphaneが指摘したようにコメントから、上記のコマンドは、ASCII文字のみを含むテキストを返します。または、少なくともASCIIでエンコードされた文字(ファイルエンコーディングによって異なります。)
まったく異なるアプローチは、次のことですiconv
。
iconv -c -t ascii file.in >file.out
これにより、ファイルがASCIIエンコードに変換され、変換できないすべての文字(行ではない)が自動的に削除されます。