Ale*_*man 194
你可以简单地说:
(head; tail) < file.txt
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因需要使用管道,那么像这样:
cat file.txt | (head; tail)
Run Code Online (Sandbox Code Playgroud)
注意:如果file.txt中的行数小于head的默认行+ tail的默认行,则会打印重复的行.
kev*_*kev 18
ed
是个 standard text editor
$ echo -e '1+10,$-10d\n%p' | ed -s file.txt
Run Code Online (Sandbox Code Playgroud)
小智 13
对于纯流(例如,来自命令的输出),您可以使用'tee'来分叉流并将一个流发送到头部和一个到尾部.这需要使用bash(+/dev/fd/N)的'>(list)'功能:
( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )
Run Code Online (Sandbox Code Playgroud)
或使用/ dev/fd/N(或/ dev/stderr)加上具有复杂重定向的子壳:
( ( seq 1 100 | tee /dev/fd/2 | head 1>&3 ) 2>&1 | tail ) 3>&1
( ( seq 1 100 | tee /dev/stderr | head 1>&3 ) 2>&1 | tail ) 3>&1
Run Code Online (Sandbox Code Playgroud)
(这些都不适用于csh或tcsh.)
对于具有更好控制的东西,您可以使用此perl命令:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
Run Code Online (Sandbox Code Playgroud)
基于JF 塞巴斯蒂安的评论:
cat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在一个管道中以不同的方式处理第一行和其余行,这对于处理 CSV 数据非常有用:
{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
Run Code Online (Sandbox Code Playgroud)
N*2 2 4 6
我们花了很多时间才最终完成这个解决方案,该解决方案似乎是唯一涵盖所有用例的解决方案(到目前为止):
command | tee full.log | stdbuf -i0 -o0 -e0 awk -v offset=${MAX_LINES:-200} \
'{
if (NR <= offset) print;
else {
a[NR] = $0;
delete a[NR-offset];
printf "." > "/dev/stderr"
}
}
END {
print "" > "/dev/stderr";
for(i=NR-offset+1 > offset ? NR-offset+1: offset+1 ;i<=NR;i++)
{ print a[i]}
}'
Run Code Online (Sandbox Code Playgroud)
功能列表:
小智 6
(sed -u 10q; echo ...; tail) < file.txt
Run Code Online (Sandbox Code Playgroud)
(head;tail)
主题的另一个变体,但是避免了小文件的初始缓冲区填充问题。
head -10 file.txt; tail -10 file.txt
除此之外,您需要编写自己的程序/脚本。
这里的问题是面向流的程序事先不知道文件的长度(因为如果它是真正的流,则可能没有文件的长度)。
tail
诸如缓冲看到的最后 n 行并等待流结束,然后打印之类的工具。
如果您想在单个命令中执行此操作(并使其适用于任何偏移量,并且如果重叠,则不要重复行),您将必须模拟我提到的这种行为。
试试这个 awk:
awk -v offset=10 '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile
Run Code Online (Sandbox Code Playgroud)