webdevqa.jp.net

Ubuntuターミナルで2つのトークン間の文字列をテキストファイルで検索して出力を保存する方法は?

Ubuntuターミナルでこのパターンのテキストファイルを検索し、出力をテキストファイルとして保存するにはどうすればよいですか?

データの長いリストで、文字列「abc」と文字列「cde」の間のすべてを探しています。

例えば:

blah blah abc fkdljgn cde blah
blah blah blah blah blah abc skdjfn cde blah

上記の例では、次のような出力を探しています。

fkdljgn
skdjfn

データ出力をテキストファイルとして保存できることも重要です。

Grepまたはagrepを使用できますか。使用できる場合、その形式は何ですか?

5
Blue

表示する出力を取得するには、次のコマンドを実行します

grep -Po 'abc \K.*(?= cde)'  file.txt > outfile.txt

Pは、 lookarounds および\KをサポートするPerl互換正規表現をアクティブにします。これは、「この時点までに一致するものをすべて破棄する」ことを意味します。 -ogrepにより、行の一致した部分のみを印刷するため、正の先読み(?=cde)と\Kを組み合わせて、 abcおよびcde> outfile.txtは、結果をファイルoutfile.txtに保存します。

他のいくつかのアプローチ:

  • sed

    sed -r 's/.*abc (.+) cde.*/\1/' file.txt > outfile.txt
    

    ここで、括弧はパターンをキャプチャし、\1として参照できます。 's/source/replacement/'は置換演算子であり、sourcereplacementに置き換えます。この場合、abccdeの間にあるものを除いてすべてを削除します。

  • Perl

    Perl -pe 's/.*abc (.+) cde.*/$1/' file.txt > outfile.txt
    

    上記と同じように、-pは「入力ファイルを1行ずつ読み取り、-eとして指定されたスクリプトを適用して印刷する」という意味です。

  • awk

     awk -F'abc|cde' '{print $2}' file.txt > outfile.txt
    

    ここでの考え方は、フィールド区切り文字をabcまたはcdeに設定することです。これらの文字列が各行で一意であると仮定すると、2番目のフィールドは2つのフィールドの間のフィールドになります。ただし、これには、先​​頭と末尾のスペースが含まれ、それらを削除して別のawkを通過させます。

    awk -F'abc|cde' '{print $2}' file | awk '{print $1}'
    
  • GNU awkgawk)。上記はgawkでも完全に機能します。より複雑な処理を行い、パターンをキャプチャする必要がある場合に備えて、これを含めています。

    gawk '{print gensub(/.*abc (.*) cde.*/,"\\1", "g",$0);}' file.txt > outfile.txt
    

    これはPerlおよびsedのものと同じ基本的な考え方ですが、gawkの gensub() 関数を使用します。

11
terdon

そのために正規表現を使用したいとします。私はUNIX正規表現ではそれほど経験がありませんが、このようなものはうまくいくはずです

grep -Po '(?<=abc ).*(?= cde)' test.txt > output.txt

編集:構文エラーは引用符がないために発生しましたが、古い提案は機能しませんでした(?<=xxx)これはゼロ幅後読みアサーションと呼ばれ、<なしで見てください先に。 -PはPerlスタイルの正規表現をアクティブにし、-oは一致のみを出力します。

これを試して、abc mymatch cdeを含むテキストファイルで問題なく動作しました。

3
PTS