通过中间带有“...”的管道打印文件的前几行和最后几行

Sam*_*Sam 16 bash shell tail

问题描述

这是我的文件

1
2
3
4
5
6
7
8
9
10
Run Code Online (Sandbox Code Playgroud)

我想通过管道发送该文件的 cat 输出并接收该文件

% cat file | some_command
1
2
...
9
10
Run Code Online (Sandbox Code Playgroud)

尝试过的解决方案

这是我尝试过的一些解决方案及其输出

% cat temp | (head -n2 && echo '...' && tail -n2)
1
2
...
Run Code Online (Sandbox Code Playgroud)
% cat temp | tee >(head -n3) >(tail -n3) >/dev/null
1
2
3
8
9
10
# I don't know how to get the ...
Run Code Online (Sandbox Code Playgroud)
% cat temp | sed -e 1b -e '$!d'
1
10

% cat temp | awk 'NR==1;END{print}'
1
10
# Can only get 2 lines
Run Code Online (Sandbox Code Playgroud)

daw*_*awg 8

一个 awk:

awk -v head=2 -v tail=2 'FNR==NR && FNR<=head
FNR==NR && cnt++==head {print "..."}
NR>FNR && FNR>(cnt-tail)' file file
Run Code Online (Sandbox Code Playgroud)

或者,如果单次传递很重要(并且内存允许),您可以使用perl

perl -0777 -lanE 'BEGIN{$head=2; $tail=2;}
END{say join("\n", @F[0..$head-1],("..."),@F[-$tail..-1]);}' file   
Run Code Online (Sandbox Code Playgroud)

或者,一次 awk:

awk -v head=2 -v tail=2 'FNR<=head
{lines[FNR]=$0}
END{
    print "..."
    for (i=FNR-tail+1; i<=FNR; i++) print lines[i]
}' file
Run Code Online (Sandbox Code Playgroud)

或者,直接成为穴居人并没有什么错,比如:

head -2 file; echo "..."; tail -2 file
Run Code Online (Sandbox Code Playgroud)

任何这些印刷品:

1
2
...
9
10
Run Code Online (Sandbox Code Playgroud)

效率而言,这里有一些统计数据。

对于小文件(即小于 10 MB 左右),所有这些都小于 1 秒,而“穴居人”方法为2 毫秒

然后我创建了一个 1.1 GB 的文件seq 99999999 >file

  • 两次通过 awk:50 秒
  • 一次 Perl:10 秒
  • 一次 awk:29 秒
  • “穴居人”:2 MS

  • 现在处理行数小于头尾线的情况,以及头尾线相交的情况^^ (2认同)