連続した文字列間のテキストの削除

連続した文字列間のテキストの削除

テキストファイルから指定された2つの文字列の間のすべてのテキストを削除する必要があります。文字列は別の行にあってもかまいません。たとえば、次のテキストファイルでは

@article{ginsberg_lifespan_2018,
    title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
    abstract = {test1
test2  abstract {NS}

test3},
    language = {en},
    urldate = {2018-12-05},
    author = {Ginsberg, Daniel},
    month = dec,
    year = {2018}
}

@article{higaki_two-dimensional_2017,
    title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
    abstract = {We study the two-dimensional stationary Navier-Stokes equations with rotating effect in the whole space. The unique existence and the asymptotics of solutions are obtained without the smallness assumption on the rotation parameter.},
    journal = {arXiv:1703.07372 [math]},
    author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
    month = mar,
    year = {2017},
    note = {arXiv: 1703.07372},
    keywords = {Mathematics - Analysis of PDEs}
}

この文字列を含む常に行の末尾にあるものabstract =とaの間のすべての項目を削除したいと思います。},つまり、次のような出力が必要です。

@article{ginsberg_lifespan_2018,
    title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
    language = {en},
    urldate = {2018-12-05},
    author = {Ginsberg, Daniel},
    month = dec,
    year = {2018}
}

@article{higaki_two-dimensional_2017,
    title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
    journal = {arXiv:1703.07372 [math]},
    author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
    month = mar,
    year = {2017},
    note = {arXiv: 1703.07372},
    keywords = {Mathematics - Analysis of PDEs}
}

この種の質問があることを知って、公開されたソリューションを試してみました。たとえば、私は

perl -0777 -pe 's/abstract = .*},\n/\n/gs'

abstract =ただし、これにより、連続する項目ではなく、最初の項目と最後の項目の間のテキストが削除されます},。これは私が得たものです。

@article{ginsberg_lifespan_2018,
    title = {On the lifespan of three-dimensional gravity water waves with vorticity},

    keywords = {Mathematics - Analysis of PDEs}
}

必要な結果を得るには、このコマンドをどのように変更する必要がありますか?

答え1

$ sed '/abstract = .*},$/d; /abstract = /,/},$/d' <file
@article{ginsberg_lifespan_2018,
    title = {On the lifespan of three-dimensional abstract gravity water waves with vorticity},
    language = {en},
    urldate = {2018-12-05},
    author = {Ginsberg, Daniel},
    month = dec,
    year = {2018}
}

@article{higaki_two-dimensional_2017,
    title = {On the two-dimensional steady {Navier}-{Stokes} equations related to flows around a rotating obstacle},
    journal = {arXiv:1703.07372 [math]},
    author = {Higaki, Mitsuo and Maekawa, Yasunori and Nakahara, Yuu},
    month = mar,
    year = {2017},
    note = {arXiv: 1703.07372},
    keywords = {Mathematics - Analysis of PDEs}
}

まず、1行のabstract項目全体を削除しようとしますが、それでも機能しない場合は、複数行の項目を削除しようとしますabstract。複数行エントリは、インクルードabstract =行から終わる次の行までの行セットです},

注釈付きsedスクリプト:

/abstract = .*},$/d    # delete complete abstract line, skip to next input line
/abstract = /,/},$/d   # delete multi-line abstract entry

たとえば、開始文字列をより具体的に指定する必要がある場合は、これらの式の一部を代わり^[[:blank:]]*abstractに使用できます。この行の前にはスペースまたはタブのみがabstract許可されています。abstract =

答え2

たとえば、sedの解決策は、各開始文字列と終了文字列を次に変換することです。一つ文字なので、正規表現を使用して文字を防止(否定)できます[^…]

文字に変換します(%(開始)と#(終了)がファイルに表示されないとし、後で詳しく説明します):

<<<infile sed 's/abstract =/%/g; s/},\n/#/g'

その後、最初の項目から選択(および削除)できます。スタート( %)特徴初めて終わり#)文字の後:

sed 's/%[^#]*#//g'

[^#]ゲームをプレイするために必要欲はない

一部の区切り文字がまだ存在する可能性があるため、それらを復元する必要があります。

sed 's/%/abstract =/g; s/#/},\n/g'    # assuming GNU sed.

もちろん、パターンが別の行に表示される可能性があるため、上記の内容をファイル全体に適用する必要があります。したがって、予約済みスペースにファイル全体をキャプチャします。

sed 'H;1h;$!d;g;'

コマンドライン全体で、次の操作を行います。

 <infile sed 'H;1h;$!d;g;  s/abstract =/%/g; s/},\n/#/g;
                           s/%[^#]*#//g ;
                           s/%/abstract =/g; s/#/},\n/g'

選択した文字が入力ファイルに存在する可能性がある場合は、テキストファイルに存在しない他の明示的な区切り文字を選択できます。

ASCIIでは、SOH(ヘッダ開始)およびSTX(テキスト開始)として01知られる値を持つ文字(バイト)02は「制御文字」であり、テキストファイルでは非常にまれです。これを使用するには、シェルスクリプトを作成することをお勧めします。

 #!/bin/bash
 start=$'\1'
 end=$'\2'
 startpattern='abstract ='
 endpattern=$'},\\\n'         # The newline needs a `\` for sed to work.

 sed 'H;1h;$!d;g;
      s/'"$startpattern"'/'"$start"'/g;
      s/'"$endpattern"'/'"$end"'/g;
      s/'"$start"'[^'"$end"']*'"$end"'//g;
      s/'"$start"'/'"$startpattern"'/g;
      s/'"$end"'/'"$endpattern"'/g'  <infile

答え3

あなたは正しいです。ここではこのような質問が数えきれないほど多く提起されました。どのくらい行くのでしょうか?

sed '/abstract.*{/ {:L; /}/{d; b;}; N; bL; }' file

わかりますか?一致したら、abstract必要に応じて見つかるまで繰り返します}

編集する:変更されたリクエストを許可する:

sed '/abstract.*{/ {:L; /},$/{d; b;}; N; bL; }' file

答え4

Perlコードはほぼ完成しました。いくつか変更するだけです。

 perl -0777pe 's/abstract = .*?\},\n/\n/msg'

/ sフラグは.を改行と一致させ、.*?を非欲張りにします。

関連情報