行からあるパターンの前のすべての項目と別のパターンの後のすべての項目を削除するにはどうすればよいですか?

行からあるパターンの前のすべての項目と別のパターンの後のすべての項目を削除するにはどうすればよいですか?

次のファイルから:

Lorem ipsum dolor sat amet, consectetuer adipiscing elit. Ut eu metus id lectus前庭脊椎。マエケナスロングス。

consectetuer前後の内容をすべて削除したいと思いますelit

私が望む出力:

consectetuer adipiscing elit.

どうすればいいですか?

答え1

私はsedを使用します

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

sed s/find/replace/ デコード構文:

  • s/^.*- 置換は行^の先頭()から始まり、次に次の項目(.*)が続きます。
  • \(- 名前付きブロックの開始
  • consectetuer.*elit\.- 最初の単語と一致し、最後の単語(この場合は末尾(エスケープ)点を含む)までのすべての(.*)が一致します。
  • \)- 名前付きブロックの終わり
  • 他のすべての項目(.*)を行末($)と一致させます。
  • /- 代替検索セクションの終わり
  • \1\(-\)上と上の間の名前ブロックに置き換えられます。
  • /- 交換の終わり

答え2

もし各ライン開始と終了のパターンが含まれている場合、最も簡単な方法ではなくgrep削除各行の始めと終わりには、2つのパターン間の内容を簡単に出力できます。一致するものだけを出力する-oGNUのオプション:grep

grep -o 'consectetuer.*elit' file

注:上記のように、この方法はファイル内のすべての行をこの方法で解析できる場合にのみ機能します。そしてこれはすべての一般的なユースケースの80%を占めます。

答え3

この質問のタイトルがなぜ編集されたのかわかりません。」ファイルから「到着する」行からOPは複数行にまたがる可能性を排除しませんが、例には1行しかないように見えますが、ここでは複数行のソリューションを使用すると役に立ちます。

これは交差した線ですfrom1to2この答えは、ファイルに存在する場合に機能します。):

from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"

例:

[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl

home
 
def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl

home
 
def elit
[xiaobai@xiaobai tmp]$ 

引用:シェルパラメータ拡張

答え4

パール方式。これは本質的に同じです。マイクVsed答え:

perl -pe 's/.*(consectetuer.*elit).*./$1/' file

-p「与えられたスクリプトを適用した後、各行を印刷します」を意味します-e。はs/foo/bar/代替演算子fooです。bar括弧はパターンをキャプチャして置換に使用できるようにします。最初にキャプチャされたパターンはで$1、2番目のパターン$2はです。

consectetuerしたがって、このコマンドは、().*consectetuerの前のすべての項目、elit.*elit)の前のすべての項目、および次の行の.*終わり()の前のすべての項目を一致させ、それをキャプチャされたパターンに置き換えます。

関連情報