Charlie
Charlie

Reputation: 2271

BASH - How to retrieve a single line from the file?

How to retrieve a single line from the file?

file.txt
"aaaaaaa"
"bbbbbbb"
"ccccccc"
"ddddddd"

I need to retrieve the line 3 ("ccccccc") Thank you.

Upvotes: 3

Views: 561

Answers (7)

gniourf_gniourf
gniourf_gniourf

Reputation: 46823

Since, as usual, all the other answers involve trivial and usual stuff (pipe through grep then awk then sed then cut or you-name-it), here's a very unusual and (sadly) not very well-known one (so, I hereby claim that I have the most original answer):

mapfile -s2 -n3 -t < input.txt
echo "$MAPFILE"

I would say this is fairly efficient (mapfile is quite efficient and it's a bash builtin).

Done!

Upvotes: 1

ghoti
ghoti

Reputation: 46826

Are other tools than bash allowed? On systems that include bash, you'll usually find sed and awk or other basic tools:

$ line="$(sed -ne 3p input.txt)"
$ echo "$line"

or

$ read line < <(awk 'NR==3' input.txt)
$ echo "$line"

or if you want to optimize this by quitting after the 3rd line is read:

$ read line < <(awk 'NR==3{print;nextfile}' input.txt)
$ echo "$line"

or how about even simpler tools (though less optimized):

$ line="`head -n 3 input.txt | tail -n 1`"
$ echo "$line"

Of course, if you really want to do this all within bash, you can still make it a one-liner, without using any external tools.

$ for (( i=3 ; i-- ; )); do read line; done < input.txt
$ echo "$line"

There are many ways to achieve the same thing. Pick one that makes sense for your task. Next time, perhaps explain your overall needs a bit better, so we can give you answers more applicable to your situation.

Upvotes: 1

koola
koola

Reputation: 1734

Fast bash version;

while (( ${i:-1} <= 3 )); do
  (( $i == 3 )) && read -r line; (( i++ ))
done < file.txt

Output

echo "$line" # Third line
"ccccccc"

Explanation

  • while (( ${i:-1} <= 3 )) - Count until $i equals 3 then exit loop.
  • (( $i == 3 )) - If $i is equal to 3 execute read line.
  • read -r line - Read the file line into variable $line.
  • (( i++ )) - Increment $i by 1 at each loop.
  • done < file.txt - Pipe file into while loop.

Upvotes: 0

alinsoar
alinsoar

Reputation: 15793

There are many possibilities: Try so:

sed '3!d' test

Here is a very fast version:

sed "1d; 2d; 3q"

Upvotes: 1

sampson-chen
sampson-chen

Reputation: 47267

Here's a way to do it with awk:

awk 'FNR==3 {print; exit}' file.txt

Explanation:

  • awk '...' : Invoke awk, a tool for manipulating files line-by-line. Instructions enclosed by single quotes are executed by awk.
  • FNR==3 {print; exit}: FNR stands for "File Number Records"; just think of it as "number of lines read so far for this file". Here we are saying, if we are on the 3rd line of the file, print the entire line and then exit awk immediately so we don't waste time reading the rest of a large file.
  • file.txt: specify the input file as an argument to awk to save a cat.

Upvotes: 1

Jo So
Jo So

Reputation: 26501

sed is your friend. sed -n 3p prints the third line (-n: no automatic print, 3p: print when line number is 3). You can also have much more complex patterns, for example sed -n 3,10p to print lines 3 to 10.

If the file is very big, you may consider to not cycle through the whole file, but quit after the print. sed -n '3{p;q}'

Upvotes: 4

ruakh
ruakh

Reputation: 183251

If you know you need line 3, one approach is to use head to get the first three lines, and tail to get only the last of these:

varname="$(head -n 3 file.txt | tail -n 1)"

Another approach, using only Bash builtins, is to call read three times:

{ read ; read ; IFS= read -r varname } < file.txt

Upvotes: 1

Related Questions