我想打印第二行之前的所有内容开始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 输入文件