shell sed搜索范围并打印第一个集合

exdqitrt  于 2023-05-29  发布在  Shell
关注(0)|答案(6)|浏览(195)

我有一个文件如下

myname
_       something
_       something
_       something
myname
_       something
_       something
myname
_       something
and it follows and no standard other than myname word.

现在我想打印第一组从myname到直到myname找到的搜索,如下所示。

myname
_       something
_       something
_

我尝试使用以下方法,但它不起作用。

sed -n -e '/myname/,/myname/ p' file

它会打印所有集合。
我也试过,但没有成功。

sed -n '/myname/,$ p;/myname/q'
zz2j4svz

zz2j4svz1#

下面是awk的另一种方法:

awk '/myname/{++c}c<2' file
$ cat file
myname
_       something
_       something
_       something
myname
_       something
_       something
myname
_       something
$ awk '/myname/{++c}c<2' file
myname
_       something
_       something
_       something

如果你的文件太大:

awk '/myname/{++c}c==2{exit}1' file
7uzetpgm

7uzetpgm2#

awk  '/myname/{if(b) exit; else b=1}1' filename


$ cat temp.txt
myname
_       something
_       something
_       something
myname
_       something
_       something
myname
_       something

$ awk  '/myname/{if(b) exit; else b=1}1' temp.txt
myname
_       something
_       something
_       something
fkvaft9z

fkvaft9z3#

这可能对你有用(GNU sed):

sed '/myname/{:a;n;//Q;$!ba}' file

查找模式myname,然后设置一个循环,打印当前行,如果新的当前行包含上述模式或循环,则退出(但不打印)。
另一种方法是使用类似grep的选项-n

sed -n '/myname/{:a;p;n;//q;ba}' file
hkmswyz6

hkmswyz64#

mawk '(_+=/myname$/)*_>_{ exit }_'
zf2sa74q

zf2sa74q5#

这是一个Bash解决方案。

n=0
while read line; do
    [[ $line == myname ]] && ((n++))
    [ $n -gt 1 ] && break
    echo $line
done < file
rpppsulh

rpppsulh6#

我有一些sed唯一的解决方案给你:
给定这个输入文件

$ cat file
myname
_       something
_       something
_       something
myname
_       something
_       something
myname
_       something
sed -n -e '/myname/,$ { 1,/myname/p }' file

产生此输出

myname
_       something
_       something
_       something
myname

添加| sed '$d'将删除最后一行,因此
sed -n -e '/myname/,$ { 1,/myname/p }' file | sed '$d'
给出此输出

myname
_       something
_       something
_       something

说明

sed -n抑制行输出/myname/,$选择从myname到文件末尾的所有行。
{ 1,/myname/p }将从选中的行打印到下一个myname的所有行,最后| sed ‘$d’删除上一个命令的最后一行。
显然,这也适用于第一个和第二个 * regex * 不同的情况。

奖金

sed -n -e '/myname/,$ { 1,/myname/ { /myname/!p } }' file

打印如下:

_       something
_       something
_       something

为什么原始选择不起作用

起初我不明白为什么你的剧本不起作用。我一直在尝试类似的东西,一直在寻找原因,为什么它不是,只是假设sed是,莫名其妙地,打破了。
然后我意识到:sed处理整个文件,并应用您的(和我的!)模式,它会找到几个myname … myname的例子,并将它们全部打印出来!
如果start和end /regexs/不同,那么下面的例子就可以了(比如你的文件混合了myname和othername)

sed -n -e '/myname/,/othername/ { p; /othername/q }' file

如果你不希望输出的最后一行包含 othername,你仍然需要删除它。

相关问题