sed工作流程相关查询:打印命令作为多命令的一部分时作为范围,但当单独使用时作为模式

Query related to working flow of sed: Print command act as range when part of multicommand but act as pattern when used individually

我正在查询 this question

中发布的命令

据我了解 sed 流程

sed -n '1!G;h;$p'

Sed 流程在每一行的循环中从左到右发生。意味着输入中的每一行都会尝试执行分号指定的每个命令。在上面的示例中,--sed 将第一行读入模式 space ---现在它有三组命令,它将尝试在每一行上执行 ---> 它读取第一个命令 1!G 它将尝试在线执行它,但由于当前读取的行是第一行并且提供了否定,它将跳到第二个命令,然后它将尝试执行第三个命令,即 $p 但由于第三个命令是打印最后一行,它将被跳过对于所有连续的行,直到最后一行。

如果我上面的理解是对的,那么对于下面的命令

sed -n '1!G;h;7p;8p' 

当读取第 8 行时,它应该打印第 7 和第 8 行,打印命令不应应用于任何其他行。

但是它以相反的顺序打印了 15 行。 它打印 1-8 行,然后再打印 1-7 行。 谁能帮忙解释一下。

根据我的理解和 sed 文档sed 按从左到右的顺序逐行运行 *但上面的命令似乎再次处理实体文件

发生的事情不是打印 1 到 8 行,而是将 7 行存储在模式 space 中打印它们,然后读取第 8 行并再次打印模式 space。

基于以上观察,对于读取的每一行,sed 作用于模式 space。

然后执行以下命令

sed -n '1!G;h;7p'

由于命令是按顺序执行的,打印命令应该只在第 7 行被读取时执行并且应该打印但是它打印了 1-7 行的模式 space

因此 7p 的字面意思应该是打印第 7 行 但在这里它充当范围,意味着如果模式 space 有第 7 行输入然后打印 1-7.

sed '7p' -n ---> 打印第 7 行

sed -n '1!G;h;7p'---> 打印 1-7 行。

sed -n '1!G;h;1,7p' ---> 打印 1、1-2、1-3、1-4、1-5、1-6、1-7 行

有人可以解释为什么会这样吗?

Means every single line in input it will try to execute every single commands specified by semicolon.

sed 中的命令由 换行符和 分号分隔。

is supplied it will skip to second command, then it will try to execute third

是的,它会跳过 G但不会 h。它将跳过第一个命令。模式 space 将被添加到 hold space.

1!G   # when not on first line do `G`
h     # do `h`, always
$p    # on last line print

it was printing 1-7 line of patterm space

当然,h保留每行 space,并且 G每次都删除它。所以在第 7 行有 6 行保留 space,它们是 Grabbed,添加到模式 space,然后是 hold,然后是 7p 打印。

由于 G + h 的工作方式,它们的顺序相反 - h 将第一行置于保留状态 space,然后是第二行 [=14] =] appends pattern space 中的行,所以第一行后面是第二行,然后 h 将其保留 space - 所以它们将以相反的顺序排列。

事件:

> seq 10 | sed -n '1!G;h;3p'

- read first line to pattern space
        - pattern space is `1`
   - `1!G` - ignored for first line
   - `h` - `1` is put into hold space
         - hold space is `1`
   - `3p` - ignored, not third line

- read second line to pattern space
        - pattern space is `2`
   - `1!G` - `G` grabs hold space to pattern space with a newline
        - pattern space is `2\n1`
   - `h`
        - hold space is `2\n1`
   - `3p` - ignored, not third line

- read third line to pattern space
        - pattern space is `3`
   - `1!G` - `G` grabs hold space to pattern space with a newline
        - pattern space is `3\n2\n1`
   - `h`
        - hold space is `3\n2\n1`
   - `3p` - third line, so we print pattern space with a newline
        - print `3\n2\n1\n` - so you see the output in reverse

why it was occuring?

因为 Gh 命令正在执行。


--debug 好看:

$ printf "%s\n" one two three four | sed --debug -n '1!G;h;3p'
SED PROGRAM:
  1! G
  h
  3 p
INPUT:   'STDIN' line 1
PATTERN: one
COMMAND: 1! G
COMMAND: h
HOLD:    one
COMMAND: 3 p
END-OF-CYCLE:
INPUT:   'STDIN' line 2
PATTERN: two
COMMAND: 1! G
PATTERN: two\none
COMMAND: h
HOLD:    two\none
COMMAND: 3 p
END-OF-CYCLE:
INPUT:   'STDIN' line 3
PATTERN: three
COMMAND: 1! G
PATTERN: three\ntwo\none
COMMAND: h
HOLD:    three\ntwo\none
COMMAND: 3 p
three
two
one
END-OF-CYCLE:
INPUT:   'STDIN' line 4
PATTERN: four
COMMAND: 1! G
PATTERN: four\nthree\ntwo\none
COMMAND: h
HOLD:    four\nthree\ntwo\none
COMMAND: 3 p
END-OF-CYCLE: