SEDで[すべての記号]を指定する方法は?

SEDで[すべての記号]を指定する方法は?

私は非常に大きなテキストファイルから外国語や他のキーボード以外の文字を削除するために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}grep1行あたりの機能(標準モード)のため、改行文字は制御文字として含まれません。 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が含まれます。CPOSIX[: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エンコードに変換され、変換できないすべての文字(行ではない)が自動的に削除されます。

関連情報