Reputation: 9355
I am trying to get a specific line from a text file.
So far, online I have only seen stuff like sed, (I can only use the sh -not bash or sed or anything like that). I need to do this only using a basic shell script.
cat file | while read line
do
#do something
done
I know how to iterate through lines, as shown above, but what if I just need to get the contents of a particular line
Upvotes: 156
Views: 375944
Reputation: 12757
You could use sed
command.
If the preferred line number is 5:
sed -n '5p' filename #get the 5th line and prints the value (p stands for print)
If the preferred line number is a range, e.g. 1-5 lines:
sed -n '1,5p' filename #get the 1 to 5th line and prints the values
If need to get 1st and 5th line only, e.g. 1st Line, 5th Line:
sed -n '1p;5p;' filename #get the 1st and 5th line values only
Upvotes: 6
Reputation: 814
Assuming the question was asked for bash, here is the fastest simplest way to do this.
readarray -t a <file ; echo ${a[5-1]}
You may may discard array a when not needed anymore.
Upvotes: 2
Reputation: 1847
#!/bin/bash
for i in {1..50}
do
line=$(sed "${i}q;d" file.txt)
echo $line
done
Upvotes: 1
Reputation:
I didn't particularly like any of the answers.
Here is how I did it.
# Convert the file into an array of strings
lines=(`cat "foo.txt"`)
# Print out the lines via array index
echo "${lines[0]}"
echo "${lines[1]}"
echo "${lines[5]}"
Upvotes: 2
Reputation: 401
Best performance method
sed '5q;d' file
Because sed
stops reading any lines after the 5th one
Update experiment from Mr. Roger Dueck
I installed wcanadian-insane (6.6MB) and compared sed -n 1p /usr/share/dict/words and sed '1q;d' /usr/share/dict/words using the time command; the first took 0.043s, the second only 0.002s, so using 'q' is definitely a performance improvement!
Upvotes: 27
Reputation: 7497
Assuming line
is a variable which holds your required line number, if you can use head
and tail
, then it is quite simple:
head -n $line file | tail -1
If not, this should work:
x=0
want=5
cat lines | while read line; do
x=$(( x+1 ))
if [ $x -eq "$want" ]; then
echo $line
break
fi
done
Upvotes: 37
Reputation: 11
line=5; prep=`grep -ne ^ file.txt | grep -e ^$line:`; echo "${prep#$line:}"
Upvotes: 0
Reputation: 38145
If for example you want to get the lines 10 to 20 of a file you can use each of these two methods:
head -n 20 york.txt | tail -11
or
sed -n '10,20p' york.txt
p
in above command stands for printing.
Upvotes: 13
Reputation: 1739
Easy with perl! If you want to get line 1, 3 and 5 from a file, say /etc/passwd:
perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
Upvotes: 0
Reputation: 1344
You could use sed -n 5p file
.
You can also get a range, e.g., sed -n 5,10p file
.
Upvotes: 38
Reputation: 189327
In parallel with William Pursell's answer, here is a simple construct which should work even in the original v7 Bourne shell (and thus also places where Bash is not available).
i=0
while read line; do
i=`expr "$i" + 1`
case $i in 5) echo "$line"; break;; esac
done <file
Notice also the optimization to break
out of the loop when we have obtained the line we were looking for.
Upvotes: 1
Reputation: 212228
The standard way to do this sort of thing is to use external tools. Disallowing the use of external tools while writing a shell script is absurd. However, if you really don't want to use external tools, you can print line 5 with:
i=0; while read line; do test $((++i)) = 5 && echo "$line"; done < input-file
Note that this will print logical line 5. That is, if input-file
contains line continuations, they will be counted as a single line. You can change this behavior by adding -r
to the read command. (Which is probably the desired behavior.)
Upvotes: 2