这个sed命令如何工作:“ sed -e:a -e'$ d; N; 2,10ba'-e'P; D'”如何工作?

时间:2019-04-13 10:09:10

标签: sed

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

<nav>
    <div class="nav-brand">
      <a>BIKE</a>
    </div>
    <div class="hamburger">
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
    </div>   
    <ul class="nav-links">
      <li><a href="#">About</a></li>
      <li><a href="#">Design</a></li>
      <li><a href="#">Gallery</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>

但是我不明白它是如何工作的。有人可以帮我解释一下吗?

更新:

这是我对该命令的理解:

  1. 第一个脚本表明已定义标签“ sed -e :a -e '$d;N;2,10ba' -e 'P;D' ”。
  2. 第二个脚本表示它首先确定是否 当前读取模式空间的行是最后一行。如果是, 执行“ a”命令将其删除并重新开始下一个周期;如果 不,跳过“ d”命令;然后执行“ d”命令:附加一个新的 从输入文件到模式空间,然后执行 “ N”:如果当前正在读取模式空间的行是一行 在第二行到第十行中,跳转到标签“ 2,10ba”。
  3. 第三个脚本指示当前是否读入该行 模式空间不是从第2行到第10行的一行,请首先执行“ a”命令:第一行 打印模式空间中的行,然后执行“ P”命令:模式中的第一行 空间已删除。

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

2 个答案:

答案 0 :(得分:1)

:a是一个标签。地址中的$表示最后一行,d表示删除N代表将下一行追加到模式空间2,10表示第2至10行,b表示分支(即 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])

答案 1 :(得分:0)

一种更简单的手段,如果您的数据通过gnu sed保存在“ d”文件中,

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

                         ^

指向10是要删除的最后一行的数字

只需移动支撑组即可反转,即。仅获得最后10行

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