假设您有一个txt文件,同时查看前10行和后10行文件的命令是什么?
即。如果文件长度为200行,则一次查看1-10行和190-200行。
答案 0 :(得分:181)
你可以简单地说:
(head; tail) < file.txt
如果由于某种原因需要使用管道,那么就像这样:
cat file.txt | (head; tail)
注意:如果file.txt中的行数小于head的默认行数+默认的tail行数,则会打印重复的行。
答案 1 :(得分:17)
ed
是standard text editor
$ echo -e '1+10,$-10d\n%p' | ed -s file.txt
答案 2 :(得分:11)
对于纯流(例如,从命令输出),您可以使用'tee'来分叉流并将一个流发送到head和one到tail。这需要使用bash的'&gt;(列表)'功能(+ / dev / fd / N):
( 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;'
答案 3 :(得分:4)
(sed -u 10q; echo ...; tail) < file.txt
(head;tail)
主题的另一个变体,但避免了小文件的初始缓冲区填充问题。
答案 4 :(得分:3)
head -10 file.txt; tail -10 file.txt
除此之外,您还需要编写自己的程序/脚本。
答案 5 :(得分:2)
这里的问题是面向流的程序事先不知道文件的长度(因为可能没有,如果它是真正的流)。
像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
答案 6 :(得分:2)
cat 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
答案 7 :(得分:2)
花了很多时间来结束这个解决方案,似乎是唯一一个涵盖所有用例的解决方案(到目前为止):
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]}
}'
功能列表:
答案 8 :(得分:1)
嗯,你总是可以将它们连在一起。像这样,
head fiename_foo && tail filename_foo
。如果这还不够,您可以在.profile文件或您使用的任何登录文件中自己编写一个bash函数:
head_and_tail() {
head $1 && tail $1
}
然后,从shell提示符调用它:head_and_tail filename_foo
。
答案 9 :(得分:1)
file.ext的前10行,然后是最后10行:
cat file.ext | head -10 && cat file.ext | tail -10
文件的最后10行,然后是前10行:
cat file.ext | tail -10 && cat file.ext | head -10
然后您也可以将输出传输到其他地方:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
答案 10 :(得分:1)
我写了一个简单的python应用程序来执行此操作:https://gist.github.com/garyvdm/9970522
它处理管道(流)和文件。
答案 11 :(得分:0)
使用stdin,但简单易用,可用于99%的用例
#!/usr/bin/env bash
COUNT=${1:-10}
IT=$(cat /dev/stdin)
echo "$IT" | head -n$COUNT
echo "..."
echo "$IT" | tail -n$COUNT
$ seq 100 | head_and_tail 4
1
2
3
4
...
97
98
99
100
答案 12 :(得分:0)
我会说,取决于文件的大小,主动读取其内容可能不是理想的。在这种情况下,我认为一些简单的shell脚本就足够了。
这是我最近处理大量我正在分析的CSV文件的方式:
$ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done
这会打印出每个文件的前10行和后10行,同时还会打印出文件名和前后的省略号。
对于单个大文件,您可以简单地运行以下命令以达到相同的效果:
$ head somefile.csv && echo ... && tail somefile.csv
答案 13 :(得分:0)
sed -n "1,10p; $(( $(wc -l ${aFile} | grep -oE "^[[:digit:]]+")-9 )),\$p" "${aFile}"
注意: aFile 变量包含文件的完整路径。
答案 14 :(得分:0)
要打印文件的前10行和后10行,您可以尝试以下操作:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
答案 15 :(得分:0)
在@Samus_解释here关于@Aleksandra Zalcman命令的工作原理的基础上,当你无法快速发现尾部开始的位置而不计算线条时,这种变化很方便。
{ head; echo "####################\n...\n####################"; tail; } < file.txt
或者,如果您开始使用20行以外的其他内容,则行数可能会有所帮助。
{ head -n 18; tail -n 14; } < file.txt | cat -n
答案 16 :(得分:0)
我一直在寻找这个解决方案。用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] }' ; }
答案 17 :(得分:0)
借鉴上述想法(测试bash&amp; zsh)
但使用别名&#39;帽子&#39;头和尾巴
alias hat='(head -5 && echo "^^^------vvv" && tail -5) < '
hat large.sql
答案 18 :(得分:0)
要处理管道(流)和文件,请将其添加到.bashrc或.profile文件中:
headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' ; }
然后你不仅可以
headtail 10 < file.txt
但也
a.out | headtail 10
(当10超过输入的长度时,这仍会附加虚假的空白行,与普通的a.out | (head; tail)
不同。谢谢,以前的回答者。)
注意:headtail 10
,而不是headtail -10
。
答案 19 :(得分:0)
为什么不使用sed
执行此任务?
sed -n -e 1,+9p -e 190,+9p textfile.txt