打印第 n 个匹配行之前/之后的所有内容

打印第 n 个匹配行之前/之后的所有内容

我想打印第二行之前的所有内容开始with * i(星号、空格、小写字母 I) 排除该行以及该行之后的所有内容,分别包括该行。

例如,如果我有一个像这样的文本文件:

* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now
* important: go to the mall
get clothes
* important: finish homework 

我想先打印这个:

* misc: go to the park
with your dog
* important: sell badges
the bigger the pricier
24 left right now

然后是这个:

* important: go to the mall
get clothes
* important: finish homework 

我怎样才能使用 sed 来做到这一点?

我试过

sed  '/\* [^i]/,$   { /\* [^i]/,$ d}' /path/to/txt/

但它只是打印之前的所有内容第一名匹配线。

我想要两个单独的脚本来提取每个部分。

答案1

我会建议awk处理(我相信,这将更加灵活和强大):

awk '/^\* i/ && ++c == 2{ print r ORS; r=""; c=0 }
     { r=(r? r ORS:"")$0 }
     END{ print r }' file

输出:

* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now

* important: go to the mall
get clothes
* important: finish homework

对于您当前的简单情况(没有额外的逻辑) - 它可以缩短为以下内容:

awk '/^\* i/ && ++c == 2{ print "" }1' file

要单独提取所需的部分 - 仍然使用单个awk命令,但使用动态参数part,该参数接受条件值1(第一部分,前面的部分)或2(第二部分,后面的部分)。

方案:

awk -v part=[12] '/^\* i/ && ++c == 2{ if (part == 1) exit; else f=1 } part == 1 || (part == 2 && f)' FILE

用法:

- 打印“前”部分:

$ awk -v part=1 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
>         part==1 || (part==2 && f)' file
* misc: go to the park
with your dog 
* important: sell badges
the bigger the pricier
24 left right now

- 打印“后”部分:

$ awk -v part=2 '/^\* i/ && ++c==2{ if (part==1) exit; else f=1 }
>         part==1 || (part==2 && f)' file
* important: go to the mall
get clothes
* important: finish homework

答案2

你也可以使用 sed,它比 awk 更复杂

cat sedscript.sh

deb=$1
sed 's/.*/'"$deb"'\n&/
:A
/^1/{
N
/\n\* i/!bA
:B
N
/\n\* i[^\n]*$/!bB
s/\n[^\n]*$//
s/[^\n]*\n//
q
}
:C
/^2/{
N
/\n\* i/!bC
:D
N
/\n\* i[^\n]*$/!bD
s/.*\n//
:E
N
bE
q
}
d
' $2

这样称呼它:

对于第一部分

./sedscript.sh 1 个文件

对于第二部分

./sedscript.sh 2 输入文件

相关内容