次のようなテキストファイルがあります。
English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only
Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
真ん中には、English words only
とAlso English words only
の2つの行が次々にあることに注意してください。
私がする必要があるのは、これらの2行を取得し、次のように/
で区切られた1行に結合することです。
English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only / Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
次の正規表現[[:ascii:]]
でASCII文字を含む行を検索でき、[^[:ascii:]]
で非ASCIIを検索できることがわかりました。ただし、正規表現を使用して、条件に一致するnotのインスタンスを見つけるのに少し問題があります。検索する必要があるのは行without非ASCII文字。
「逆マッチング」に関するこの質問 が見つかりましたが、答えは私を超えています。
それからもちろん、互いの関係に基づいて行を一致させることは別の問題です。これらの行が次々に並んでいるときに一致させることはできますか?それが可能かどうかさえわかりません。
非ASCII文字を含まないすべての行を検索し、LibreOffice、Gedit、またはコマンドラインを使用してそれらを結合する方法はありますか?
ファイルの長さは数千行であり、よくわからないことにも注意してください。ただし、might英語のみの行が存在する可能性があります。 3または4のグループです。
[[:ascii:]]
文字クラスを知らない場合でも、sed
を使用してこのジョブを実行できるようです。その代わりに、C
またはPOSIX
ロケールを使用している限り、すべてのASCII文字を エスケープシーケンス[\d0-\d127]
の範囲で指定できます。
信頼できるはずのコマンドを次に示します。
LC_ALL=C sed -r ':a;N;s|^([\d0-\d127]+)\n([\d0-\d127]+)$|\1 / \2|;ta' file
LC_ALL=C
このコマンドに対してのみC
ロケール設定を使用します(そうしないとエラーが発生します)-r
コマンドを読みやすくするために拡張正規表現を使用します(バックスラッシュの必要性を減らします)(GNU sed
も同じ意味で-E
を認識します)。:a
ラベル-ループはここから始まります;
シェルのようにコマンドを区切りますN
次の行をパターンスペースに読み込み、\n
を置き換えることができますs|old|new|
old
をnew
に置き換えます^([\d0-\d127])\n([\d0-\d127]+)$
-ASCIIのみの2行に一致し、\1
の最初の行と\2
の2行目をキャプチャします。 ^
は行の始まり、\n
は改行、$
は行の終わりです。したがって、^line 1\nline 2$
はline 1
とline 2
全体をテストします。\1 / \2
1行目と2行目で、改行ではなく /
で区切られています。ta
-最後の検索と置換コマンドが成功した場合、ループを再度実行します。これにより、ファイルのすべての行を処理し、3行以上のall-ASCII行があるインスタンスを処理できます。Eliah Kagan に感謝します ASCII文字に一致するエスケープシーケンスの使用方法を示します =。
ASCII文字のみで構成されるwhole linesが必要な場合は、パターンを行の先頭と末尾に固定する必要があります。 grep
$ grep -P '^[[:ascii:]]*$' file
English words only
English words only
English words only
Also English words only
English words only
一部のツールは、grepの-x
や--line-regexp
などの行全体のフラグを提供します。
-x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $.
あなたが使用できるようにする:
$ grep -Px '[[:ascii:]]*' file
English words only
English words only
English words only
Also English words only
English words only
Multilineマッチングは、他の一般的なコマンドラインテキスト処理ユーティリティの多くが行ベースであるため、さらに複雑なレイヤーを追加します。 -Z
フラグを使用してgrep
にファイル全体を強制的に丸lurみさせることができますが、pcregrep
またはPerl
自体などのツールがその時点でおそらくより適切です。
解決する必要があるnext問題は、複数行一致のコンテキストで「行の開始」と「行の終了」の概念を解釈する方法です。 Regex Tutorial:Anchors :Perl
はこれらの1つであり、/m
修飾子を提供します。デフォルトのレコード区切り文字の設定を解除してファイルを丸lurみする必要があります(ここでは-0777
を使用して行います)。例えば
$ Perl -0777 -pe 's{^([[:ascii:]]+)\n([[:ascii:]]+)$}{$1 / $2}mg' file
English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ
English words only / Also English words only
English and 日本語
日本語のみ
English words only
English and 日本語
日本語のみ