質問: 約100万行のテキストファイルがあり、各行は複数の単語で構成されており、一部の行にはロシア語またはアラビア語の単語(「無効な行」と呼ばれる)が含まれています。他のすべては「良いライン」です。
状況:
- いくつかの良い行には非ASCII文字が含まれているため、非ASCII文字をすべて削除するだけでは問題は解決されません。
- すべてのラインは完全に悪いか完全に良いので、実際には状況が少し簡単になります。
だから私が思いついた解決策は次のとおりです。
sort file.txt > sorted.txt
ロシア語またはアラビア語で始まるすべての項目は最後にリストされています。次に、開始する行を手動で確認してから実行します。
head -n X sorted.txt > clean.txt
それらを削除します。これを行うよりエレガントな方法はありますか?これを行うために使用できる他のUnixツールは何ですか?
入力例:
kedi
cat
кошка
القط
candy
şeker
конфеты
كاندي
çağrı
resumé
希望の出力:
kedi
cat
candy
şeker
çağrı
resumé
答え1
これは少なくともあなたの例ではうまくいきます。
$ perl -CS -Mutf8 -lne 's{
(?= [\p{Arabic}\p{Cyrillic}] )
[\p{Arabic}\p{Cyrillic}\p{Common}\p{Inherited}] +
(?<= [\p{Arabic}\p{Cyrillic}] ) }{}xg || print' < file
kedi
cat
candy
şeker
çağrı
resumé
基本的なアイデアは、\p
コードポイントセット(この場合はアラビア語またはキリル文字)を定義することです。行が一致すると印刷されません。残念ながら、私自身も詳細を理解していません。@tchrist存在するチャット。そこから彼の説明を読んでください。今は正規表現を解読する時間がありませんが、直接理解する機会ができるように説明を追加します。ソースを見ると、以下のミニマリストバージョンよりも完全で安全であると仮定します。
私の理解の単純化されたバージョンは次のとおりです。
$ perl -CS -ne '/[\p{Arabic}\p{Cyrillic}]+/ || print' < file
これにより、アラビア語またはキリル文字を含まないすべての行が印刷されます。ただ。 STDIN、STDOUT、およびSTDERRはすべてUnicodeです-CS
。perl
その-ne
意味は、「各入力行を読み、与えられたスクリプトを適用します。行が一致しない場合は-e
アクション/foo/ || bar
を実行することを意味します。この場合、行がアラビア語またはキリル文字と一致しない場合は印刷します。bar
foo
最後に、\p{}
これは(からman perluniprops
):
The Perl regular expression "\p{}" and "\P{}" constructs give access to
most of the Unicode character properties.
これにより、アラビア語、キリル文字、または考えられるほとんどすべての文字など、さまざまな文字を一致させることができます。したがって、キャラクタークラス [\p{foo}]
スクリプトのすべての文字と一致しますfoo
。したがって、[\p{Arabic}\p{Cyrillic}]
両方のスクリプトのすべての文字が一致します。