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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这个sed命令如何:“sed -e:a -e'$ d; N; 2,10ba'-e'P; D'”工作?相关的知识,希望对你有一定的参考价值。

我看到一个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”的理解是,当sed将最后一行读入模式空间时,将执行“d”。但似乎每次执行“ba”时,无论当前行读入模式空间是否为最后一行,都将执行“d”。为什么?

答案

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

换句话说,您创建一个大小为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'文件中由gnu sed,

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

                         ^

尖头10是要移除的最后一行的数量

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

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

以上是关于这个sed命令如何:“sed -e:a -e'$ d; N; 2,10ba'-e'P; D'”工作?的主要内容,如果未能解决你的问题,请参考以下文章

Linux:使用sed命令替换时,如何写入Tab符号呢

如何使用sed命令使用正则表达式过滤文件?

BASH:如何在 sed 命令中对字符串使用 Regex Negative Lookahead?

使用 sed 命令替换

如何在sed中使用变量

将 SED 命令转换为 linux 命令