【问题标题】:How does this sed command: "sed -e :a -e '$d;N;2,10ba' -e 'P;D' " work?这个 sed 命令:“sed -e :a -e '$d;N;2,10ba' -e 'P;D'” 是如何工作的?
【发布时间】:2019-09-03 23:13:19
【问题描述】:

我看到一个sed命令删除最后10行数据:

 sed -e :a -e '$d;N;2,10ba' -e 'P;D'

但我不明白它是如何工作的。谁能帮我解释一下?

更新:

这是我对这个命令的理解:

  1. 第一个脚本表示定义了一个标签“a”。
  2. 第二个脚本表示它首先确定是否 当前读取模式空间的行是最后一行。如果是, 执行“d”命令将其删除并重新开始下一个循环;如果 不,跳过“d”命令;然后执行“N”命令:追加一个新的 从输入文件到模式空间的行,然后执行 “2,10ba”:如果当前读取模式空间的行是一行 在第 2 到第 10 行,跳转到标签“a”。
  3. 第三个脚本表明如果当前读入的行 模式空间不是第2行到第10行,先执行“P”命令:第一行 在模式空间打印,然后执行“D”命令:模式的第一行 空间被删除。

我对“$d”的理解是,“d”会在sed将最后一行读入模式空间时执行。但似乎每次执行“ba”时,都会执行“d”,而不管读入pattern space的当前行是否是最后一行。为什么?

【问题讨论】:

  • 对于不清楚的部分,请更具体地询问,并尽可能自己解释。照原样,您的问题基本上要求提供教程。
  • 您有 RTFM 或查看任何资源吗?有一些不错的,比如grymoire.com/Unix/Sed.html ...
  • 检查我更新的答案。 d 实际上只执行一次,但它会删除最多可容纳 10 行的整个模式空间。
  • 我明白了,@choroba,你的解释很清楚。,谢谢。

标签: sed


【解决方案1】:

:a 是一个标签。地址中的$ 表示最后一行,d 表示删除N 代表将下一行添加到模式空间2,10 表示第 2 到第 10 行,b 表示 branch(即 goto),P 打印模式空间的第一行,D 就像d 但如果可能在模式空间上操作。

换句话说,您创建了一个大小为 10 的滑动窗口。每行都存储在其中,一旦有 10 行,就会从顶部开始打印行。每次打印一行时,当前行存储在底部的滑动窗口中。当最后一行打印出来时,滑动窗口被删除,最后 10 行被删除。

您可以修改命令以查看被删除 (())、存储 (<>) 和由 P ([]) 打印的内容:

$ printf '%s\n'  {1..20} | \
    sed -e ':a ${s/^/(/;s/$/)/;p;d};s/^/</;s/$/>/;N;2,10ba;s/^/[/;s/$/]/;P;D'
[<<<<<<<<<<1>
[<2>
[<3>
[<4>
[<5>
[<6>
[<7>
[<8>
[<9>
[<10>
(11]>
12]>
13]>
14]>
15]>
16]>
17]>
18]>
19]>
20])

【讨论】:

  • 如果当前读入模式空间的行不是最后一行,是不是d没有被执行?
  • D 删除 P 打印的内容,如果模式空间为空,则行为类似于 d 否则它不会将另一行读入模式空间,而是继续,就好像它有,即它转到第一个 sed 命令。基本上它从模式空间的前面“弹出”一条线。
【解决方案2】:

一个更简单的方法,如果你的数据在 gnu sed 的 'd' 文件中,

sed -Ez 's/(.*\n)(.*\n){10}$/\1/' d

                         ^

指出10 是要删除的最后一行的编号

只需移动大括号组以反转,即。只获取最后 10 行

sed -Ez 's/.*\n((.*\n){10})$/\1/' d

【讨论】:

  • \1 是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 2012-01-27
  • 2015-05-18
  • 2014-06-10
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多