unix - head AND tail of file

前端 未结 20 1203
误落风尘
误落风尘 2020-12-07 11:05

Say you have a txt file, what is the command to view the top 10 lines and bottom 10 lines of file simultaneously?

i.e. if the file is 200 lines long, then view lines

相关标签:
20条回答
  • 2020-12-07 11:40

    Building on what @Samus_ explained here about how @Aleksandra Zalcman's command works, this variation is handy when you can't quickly spot where the tail begins without counting lines.

    { head; echo "####################\n...\n####################"; tail; } < file.txt
    

    Or if you start working with something other than 20 lines, a line count might even help.

    { head -n 18; tail -n 14; } < file.txt | cat -n
    
    0 讨论(0)
  • 2020-12-07 11:42

    To handle pipes (streams) as well as files, add this to your .bashrc or .profile file:

    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] }' ; }
    

    Then you can not only

    headtail 10 < file.txt
    

    but also

    a.out | headtail 10
    

    (This still appends spurious blank lines when 10 exceeds the input's length, unlike plain old a.out | (head; tail). Thank you, previous answerers.)

    Note: headtail 10, not headtail -10.

    0 讨论(0)
  • 2020-12-07 11:43

    I would say that depending upon the size of the file, actively reading in its contents may not be desirable. In that circumstance, I think some simple shell scripting should suffice.

    Here's how I recently handled this for a number of very large CSV files that I was analyzing:

    $ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done
    

    This prints out the first 10 lines and the last 10 lines of each file, while also printing out the filename and some ellipsis before and after.

    For a single large file, you could simply run the following for the same effect:

    $ head somefile.csv && echo ... && tail somefile.csv
    
    0 讨论(0)
  • 2020-12-07 11:45
    (sed -u 10q; echo ...; tail) < file.txt
    

    Just another variation on the (head;tail) theme, but avoiding the initial buffer fill issue for small files.

    0 讨论(0)
  • 2020-12-07 11:46

    For a pure stream (e.g. output from a command), you can use 'tee' to fork the stream and send one stream to head and one to tail. This requires using either the '>( list )' feature of bash (+ /dev/fd/N):

    ( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )
    

    or using /dev/fd/N (or /dev/stderr) plus subshells with complicated redirection:

    ( ( 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
    

    (Neither of these will work in csh or tcsh.)

    For something with a little better control, you can use this perl command:

    COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
    
    0 讨论(0)
  • 2020-12-07 11:47

    I wrote a simple python app to do this: https://gist.github.com/garyvdm/9970522

    It handles pipes (streams) as well as files.

    0 讨论(0)
提交回复
热议问题