提取两个匹配字符串之间的行,同时排除匹配的行

提取两个匹配字符串之间的行,同时排除匹配的行

下面是我的文件

$ 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

我需要最后匹配的字符串之间的行unziplogout即所需的输出如下

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

或者如果您出于某种原因更喜欢只使用一种工具:

$ 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

相关内容