一致する行を除いて、一致する2つの文字列の間の行を抽出します。

一致する行を除いて、一致する2つの文字列の間の行を抽出します。

以下は私のファイルです

$ cat README
login user1
run .profile
cd /u/opt
unzip -l zip file
copy files in zip file to .orig
unzip -o the zip file
cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql
logout

最後に、一致する文字列の間に行が必要ですunzip。つまり、logout希望の出力は次のようになります。

cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql

答えが必要です。

  1. 試してみると、sed -n '/unzip -o /,/logout/p' README一致する行は除外されません。

したがって、次のような結果が得られます。

unzip -o the zip file
cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql
logout

ここで提供されている他のソリューションを試しました。sedから範囲パターンに一致する行を除外する方法は?

しかし、望む結果は出ません。以下を参照してください。

$ sed '1,/unzip/d;/logout/,$d' README
copy files in zip file to .orig
unzip -o the zip file
cd /u/opt/install
./reqe21.sh
sqlplus vrcadmin/<password> @req.sql
  1. sed最後と最後unzipの間の行logout、つまり以前に共有された希望の出力を取得するためにどのように使用できますか?

答え1

これは単にsedが最も適切な仕事ではありません。この試み:

$ tac file | awk '/unzip/{exit} f; /logout/{f=1}' | tac
cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql

または何らかの理由で1つのツールのみを使用したい場合:

$ awk '/logout/{f=0} f{rec=rec $0 ORS} /unzip/{rec=""; f=1} END{printf "%s", rec}' file
cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql

答え2

入力を逆にして sed を実行します。範囲演算子を使用してブロックを選択し、同じ正規表現を再適用して境界を切り捨てます。

$ tac |
sed -e '/logout/,/unzip/!d;//!d' |
tac
cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql

または他のユーティリティなしで結果が必要な場合。私たちは予約されたスペース(圧縮解除とログアウトに制限されています)にブロックを蓄積し続けます。解凍行が再び表示されると、上書きが残っています。 Th7sは、境界ブロックを登録解除するための最後の圧縮解除を提供します。その後、罫線をカットします。これはPosixly sedです。

sed -e '
  /\n/{
    P;/\n.*\n/D;d
  }
  /unzip/,/logout/!d
  H;/unzip/h;/logout/!d
  g;D
' file

答え3

tac filename| awk '/logout/{f=1}/unzip/{f=0}f && !/logout/'|tac

出力

cd /u/opt/install
./reqe21.sh
sqlplus admin/<password> @req.sql

関連情報