How do I use Head and Tail to print specific lines of a file
head -n XX # <-- print first XX linestail -n YY # <-- print last YY lines
If you want lines from 20 to 30 that means you want 11 lines starting from 20 and finishing at 30:
head -n 30 file | tail -n 11# # first 30 lines# last 11 lines from those previous 30
That is, you firstly get first 30
lines and then you select the last 11
(that is, 30-20+1
).
So in your code it would be:
head -n $3 $1 | tail -n $(( $3-$2 + 1 ))
Based on firstline = $2
, lastline = $3
, filename = $1
head -n $lastline $filename | tail -n $(( $lastline -$firstline + 1 ))
Aside from the answers given by fedorqui and Kent, you can also use a single sed
command:
#!/bin/shfilename=$1firstline=$2lastline=$3# Basics of sed:# 1. sed commands have a matching part and a command part.# 2. The matching part matches lines, generally by number or regular expression.# 3. The command part executes a command on that line, possibly changing its text.## By default, sed will print everything in its buffer to standard output. # The -n option turns this off, so it only prints what you tell it to.## The -e option gives sed a command or set of commands (separated by semicolons).# Below, we use two commands:## ${firstline},${lastline}p# This matches lines firstline to lastline, inclusive# The command 'p' tells sed to print the line to standard output## ${lastline}q# This matches line ${lastline}. It tells sed to quit. This command # is run after the print command, so sed quits after printing the last line.# sed -ne "${firstline},${lastline}p;${lastline}q" < ${filename}
Or, to avoid any external utilites, if you're using a recent version of bash (or zsh):
#!/bin/shfilename=$1firstline=$2lastline=$3i=0exec <${filename} # redirect file into our stdinwhile read ; do # read each line into REPLY variable i=$(( $i + 1 )) # maintain line count if [ "$i" -ge "${firstline}" ] ; then if [ "$i" -gt "${lastline}" ] ; then break else echo "${REPLY}" fi fidone