假设你有一个txt文件,想要同时查看文件的前10行和后10行,应该使用什么命令?
即使文件有200行,也可以一次性查看第1-10行和190-200行。
命令:`head -n 10 filename && tail -n 10 filename | tac`
即使文件有200行,也可以一次性查看第1-10行和190-200行。
命令:`head -n 10 filename && tail -n 10 filename | tac`
你可以简单地:
(head; tail) < file.txt
如果出于某种原因需要使用管道,则可以像这样:
cat file.txt | (head; tail)
注意:如果file.txt文件的行数小于head和tail默认值之和,则会打印重复的行。head
命令消耗了文件前10行后,给出了流的尾部。(将其与对于少于20行的文件使用head < file.txt; tail < file.txt
进行比较)。只是需要注意的一个非常小的细节。(但还是值得一加。) - chepnerseq 100 | (head; tail)
只给我前10个数字。只有在更大的输入量(如seq 2000
)时,tail 才会获得一些输入。 - modulared
是一个标准文本编辑器。
$ echo -e '1+10,$-10d\n%p' | ed -s file.txt
sed
改为 ed
。 - kev(sed -u 10q; echo ...; tail) < file.txt
这仅仅是在(head;tail)主题上的另一种变化,但避免了小文件的初始缓冲填充问题。
brew install gnu-sed
才能使其正常工作。 - steveb( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )
或者使用 /dev/fd/N(或 /dev/stderr)以及带有复杂重定向的子shell:
( ( 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
(这两个命令都不能在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;'
COMMAND | { tee >(head >&2) | tail; } |& other_commands
- jfscat >/dev/null
可以解决这个问题:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
. - jfshead
和 tail
命令之间没有保证的顺序。:\ ... - Jancat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1
这样您就可以在一个管道中以不同的方式处理第一行和其余行,这对于处理CSV数据非常有用:
{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
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]}
}'
功能列表:
.bashrc
文件中的一个函数中,这样我就可以直接使用管道传递给headtail
命令。 - jamesbtatehead -10 file.txt; tail -10 file.txt
除此之外,你需要编写自己的程序/脚本。
cat
和head
或tail
进行管道传输。很高兴知道可以单独使用它们! - Paul{ head file; tail file; } | prog
(大括号内部的空格和尾部的分号是必需的) - glenn jackmanawk -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
a.out | awk -v ...
- Camille Goudeseune我一直在寻找这个解决方案。尝试使用sed自己解决,但是不知道文件/流的长度前提下的问题无法克服。在上面提供的所有选项中,我喜欢Camille Goudeseune的awk解决方案。他指出,他的解决方案在数据集足够小的情况下会留下额外的空行。在这里,我提供了他的解决方案的修改版本,可以去除多余的行。
headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }' ; }
嗯,你总是可以把它们链接在一起。像这样:head fiename_foo && tail filename_foo
。如果这还不够,你可以在你的.profile文件或任何你使用的登录文件中编写一个bash函数:
head_and_tail() {
head $1 && tail $1
}
然后,您可以从shell提示符中调用它:head_and_tail filename_foo
。