Awk 使用一个sed调用来引导第一个H行并尾随最后的T行

Awk 使用一个sed调用来引导第一个H行并尾随最后的T行,awk,sed,text-processing,Awk,Sed,Text Processing,不久前,我编写了一个C程序,通过同时执行head和tail来汇总文本文件,只需读取一次管道输入。例如: $ headtail -h 3 -t 3 < /tmp/x10 line01 line02 line03 ... 4 output lines omitted ... line08 line09 line10 但我试图将两者结合起来的尝试失败了: $ sed -n -e '1,3p; :a; $p; N; 4,$D; ba' < /tmp/x10 line01 line08 li

不久前,我编写了一个C程序,通过同时执行
head
tail
来汇总文本文件,只需读取一次管道输入。例如:

$ headtail -h 3 -t 3 < /tmp/x10
line01
line02
line03
... 4 output lines omitted ...
line08
line09
line10
但我试图将两者结合起来的尝试失败了:

$ sed -n -e '1,3p; :a; $p; N; 4,$D; ba' < /tmp/x10
line01
line08
line09
line10
$sed-n-e'1,3p;:a$PN4美元D;ba'
如果文件中有H+T>N行(类似于
cat
),它也可以工作,还可以打印一个分隔符,指示中间省略了一些行(省略的数字很好,但我可以不使用它)。

尝试:

$ seq 10 | sed -n -e '1,3{p;b}; :a; $p; N; 7,$D; ba'
1
2
3
8
9
10
7
来自于将
3
(头部)加上
3
(尾部)加上
1

如果将尾部从3增加到7,则得到整个文件:

$ seq 10 | sed -n -e '1,3{p;b}; :a; $p; N; 12,$D; ba'
1
2
3
4
5
6
7
8
9
10
12
3
(头部)加
7
(尾部)加1。)

工作原理
  • 1,3{p;b}

    对于前三行中的任何一行,我们都会打印它们(p),然后在代码中的其余命令后面分支(b)

  • :a$PN7美元D;ba

    这与之前的相同,只是这些行从未看到前三行。因此,我们必须将
    D
    命令的起点更改为
    7


    • 不需要C程序或复杂的sed脚本,您只需要一个清晰、简单、可移植、高效的awk脚本:

      $ seq 10 | awk -v h=3 -v t=3 'NR<=h; {a[NR%t]=$0} END{for (i=1; i<=t; i++) print a[(NR+i)%t]}'
      1
      2
      3
      8
      9
      10
      
      $ seq 10 | awk -v h=3 -v t=3 'NR<=h; {a[NR%t]=$0} END{print "skipped", NR-(t+h); for (i=1; i<=t; i++) print a[(NR+i)%t]}'
      1
      2
      3
      skipped 4
      8
      9
      10
      
      $seq 10 | awk-vh=3-vt=3'NR这可能适合您(GNU-sed):

      这将打印前五行和最后三行,以
      =============
      分隔

      命令使用前n行的范围,所有行都存储在保留空间中。在文件末尾,保留空间减少到所需的行数,前导换行符被分隔符替换

      另一种解决方案,内存占用较少,但仅限于标题行等于或小于尾随行:

      sed ':a;$!{N;;s/[^\n]\+/&/5;3{p;x;s/^/==========/p;x};Ta};$P;D' file
      
      在这里,前三行和后五行用分隔符打印

      $ seq 10 | awk -v h=7 -v t=5 'NR<=h; {a[NR%t]=$0} END{print "skipped", NR-(t+h); for (i=1; i<=t; i++) print a[(NR+i)%t]}'
      1
      2
      3
      4
      5
      6
      7
      skipped -2
      6
      7
      8
      9
      10
      
      sed -E '1,5p;H;$!d;x;s/.*((\n[^\n]*){3})$/\1/;s/./==========&/' file
      
      sed ':a;$!{N;;s/[^\n]\+/&/5;3{p;x;s/^/==========/p;x};Ta};$P;D' file