为什么 '1,4p' 输出所有行而不是仅输出前四行?

为什么 '1,4p' 输出所有行而不是仅输出前四行?

我有一个名为“list”的文本文件,其中包含一些随机单词:

he
she
we
his
her
with
his this this -- this
this

我运行了这个 sed 命令:

sed '1,4p' list

我认为这个 sed 命令要做的是列出该文件中的前 4 个单词,所以我认为输出将是:

he
she
we
his

但输出却是这样的:

he
he
she
she
we
we
his
his
her
with
his this this -- this
this

谁能告诉我我做错了什么或者为什么输出不同?

答案1

你忘记了默认动作sed 的作用是打印每个模式空间(行) - 因此抑制您需要添加-n开关的默认行为

sed -n '1,4p' list

答案2

用这个:

sed -n 1,4p list

或这个:

sed '1,4!d' list

更多的例子

答案3

它的一般作用是什么

您的脚本表达式将在每一行依次执行。

要在一行上执行表达式,sed首先将其复制到模式空间
然后,执行所有表达式,每个表达式都使用模式空间作为输入,并将结果写回模式空间。

因此,通常情况下,当该行的工作步骤完成后,我们就会在模式空间中得到一个最终的字符串。在大多数情况下,我们只希望将其作为输出,例如在它被多个s//命令更改后。
因为它通常很有用,所以sed打印最终的模式空间,就好像它会附加一个p表达式一样。

您已经可以看到这会导致命令的输出。

  • 该线被放入模式空间
  • 您的脚本使用以下命令打印四个匹配行的模式空间p
  • 它完成后不会更新模式空间。
  • 由于它已经位于表达式列表的末尾,因此会打印模式空间,因为它是默认完成的

请注意,它正在输出“所有行前四行” - 与“所有行而不仅仅是前四行”相反。

因此,在重复的行中,每行的第一行是您打印的内容,第二行是默认打印的内容。

选项(sed)切换默认打印图案空间:-n--quiet

sed -n 1,4p list

要查看原始命令正在执行的操作,我们可以使两种行看起来不同:在最后打印它之前,我们通过在其前面添加前缀来更改模式空间-

$ sed -e '1,4p' -e 's/^/- /'  list
he
- he
she
- she
we
- we
his
- his
- her
- with
- his this this -- this
- this

-e需要这些选项来提供多个表达式。's/^/- /' 在行开头替换任何内容-。)

相关内容