sed '1{n};p' file

sh/bash/dash/ksh/zsh等Shell脚本
回复
bellszhu
帖子: 108
注册时间: 2010-12-18 19:46

sed '1{n};p' file

#1

帖子 bellszhu » 2011-12-17 23:16

file内容如下:
bells@bells-VirtualBox ~ $ cat file
line1
line2
line3

执行命令如下:
bells@bells-VirtualBox ~ $ sed '1{n};p' file
line1
line2
line2
line3
line3

我想知道为什么line1会被输出,而且line2和line3会被输出两次??

我自己的分析:
当读第一行时, line1进入pattern space中,当执行 '1{n};p'的时候,碰到n,所以读入第二行即"line2",然后碰到p,所以输出"line2",然后读入第三行.....
想不通"line1"是什么时候输出的??还有多余的"line2"和"line3"

然后我用命令:
bells@bells-VirtualBox ~ $ sed -n '1{n};p' file
line2
line3
的输出结果符合我的分析
所以问题出在"-n"身上。。。难道sed默认当读入新的一行,就立刻输出该行的内容,而不先执行命令??

下面是info sed中的部分内容:
`sed' maintains two data buffers: the active _pattern_ space, and the
auxiliary _hold_ space. Both are initially empty.

`sed' operates by performing the following cycle on each lines of
input: first, `sed' reads one line from the input stream, removes any
trailing newline, and places it in the pattern space. Then commands
are executed;
each command can have an address associated to it:
addresses are a kind of condition code, and a command is only executed
if the condition is verified before the command is to be executed.

When the end of the script is reached, unless the `-n' option is in
use, the contents of pattern space are printed out to the output
stream, adding back the trailing newline if it was removed.(1) Then the
next cycle starts for the next input line.
keep the faith
头像
ChenFengyuan
帖子: 770
注册时间: 2008-03-23 0:39

Re: sed '1{n};p' file

#2

帖子 ChenFengyuan » 2011-12-17 23:19

还不如直接上perl :em05
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: sed '1{n};p' file

#3

帖子 fnan » 2011-12-18 22:56

kose1-2@kose1-2-desktop:~$ echo -e "a\nb\nc"|sed '=;1{n;=};p'
1 #读入第一行,执行=指令
a #由于是n指令,读入第二行之前执行默认打印
2 #读入第二行,继续前一行未完的指令,即n指令后的=指令
b #继续前一行未完的指令,即p指令
b #完成一行的指令又默认打印
3 #正常读入下一行,执行=
c #p指令
c #默认打印
kose1-2@kose1-2-desktop:~$ echo -e "a\nb\nc"|sed -n '=;1{n;=;p};p' #-n选项,没有默认打印。
1
2
b
b
3
c
kose1-2@kose1-2-desktop:~$
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: sed '1{n};p' file

#4

帖子 fnan » 2011-12-18 23:23

perl正则解决问题是大锤对绣花针,sed正则是绣花针对大锤,但不见得必输,所以说玩法不同。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
bellszhu
帖子: 108
注册时间: 2010-12-18 19:46

Re: sed '1{n};p' file

#5

帖子 bellszhu » 2011-12-21 10:09

fnan 写了:kose1-2@kose1-2-desktop:~$ echo -e "a\nb\nc"|sed '=;1{n;=};p'
1 #读入第一行,执行=指令
a #由于是n指令,读入第二行之前执行默认打印
2 #读入第二行,继续前一行未完的指令,即n指令后的=指令
b #继续前一行未完的指令,即p指令
b #完成一行的指令又默认打印
3 #正常读入下一行,执行=
c #p指令
c #默认打印
kose1-2@kose1-2-desktop:~$ echo -e "a\nb\nc"|sed -n '=;1{n;=;p};p' #-n选项,没有默认打印。
1
2
b
b
3
c
kose1-2@kose1-2-desktop:~$
谢谢了,知道了一个新的指令"=" 打印当前行号
“#由于是n指令,读入第二行之前执行默认打印” 这个man sed 中只是“n N Read/append the next line of input into the pattern space.”,并没说会默认打印。 原来会默认打印。以前以为只有内容到了hold space之后,再读入下一行才会打印的。。
keep the faith
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: sed '1{n};p' file

#6

帖子 fnan » 2011-12-21 20:28

N指令没有默认打印,只把前一行作为下一行的一部分。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
bellszhu
帖子: 108
注册时间: 2010-12-18 19:46

Re: sed '1{n};p' file

#7

帖子 bellszhu » 2011-12-22 9:27

fnan 写了:N指令没有默认打印,只把前一行作为下一行的一部分。
“只把前一行作为下一行的一部分”
理解不了!!详细解释下?
keep the faith
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: sed '1{n};p' file

#8

帖子 fnan » 2011-12-22 21:45

kose3@kose3-desktop:~$ echo -e "a\nb\nc"|sed '=;N;='
1 # 第一行
2 # 第二行
a
b #a和b看作一行处理,中间有个\n字符而已。
3
c
kose3@kose3-desktop:~$
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
bellszhu
帖子: 108
注册时间: 2010-12-18 19:46

Re: sed '1{n};p' file

#9

帖子 bellszhu » 2011-12-23 17:12

fnan 写了:kose3@kose3-desktop:~$ echo -e "a\nb\nc"|sed '=;N;='
1 # 第一行
2 # 第二行
a
b #a和b看作一行处理,中间有个\n字符而已。
3
c
kose3@kose3-desktop:~$

哦,谢谢了,我还以为用N指令后,读入的行会替换掉原先的行,原来是加了个换行符,再接着新行内容的。。
keep the faith
bellszhu
帖子: 108
注册时间: 2010-12-18 19:46

Re: sed '1{n};p' file

#10

帖子 bellszhu » 2011-12-23 17:22

明白了
小写n 和大写N
不一样
n :是Read the next line of input into the pattern space.
N: 是append the next line of input into the pattern space.


n指令在读入下一行之前会默认打印上一行的内容。

谢谢 “fnan”
keep the faith
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: sed '1{n};p' file

#11

帖子 tusooa » 2012-01-01 12:34

bellszhu 写了:file内容如下:
bells@bells-VirtualBox ~ $ cat file
line1
line2
line3

执行命令如下:
bells@bells-VirtualBox ~ $ sed '1{n};p' file
line1
line2
line2
line3
line3

我想知道为什么line1会被输出,而且line2和line3会被输出两次??
sed在没有-n的时候,当-e脚本执行完就会自动输出当前行。

代码: 全选

] ls -ld //
回复