Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to show the third line of multiple files

Tags:

linux

unix

sed

awk

I have a simple question. I am trying to check the 3rd line of multiple files in a folder, so I used this:

head -n 3 MiseqData/result2012/12* | tail -n 1

but this doesn't work obviously, because it only shows the third line of the last file. But I actually want to have last line of every file in the result2012 folder.

Does anyone know how to do that?

Also sorry just another questions, is it also possible to show which file the particular third line belongs to?

like before the third line is shown, is it also possible to show the filename of each of the third line extracted from?

because if I used head or tail command, the filename is also shown.

thank you

like image 826
john_w Avatar asked Jan 25 '23 23:01

john_w


2 Answers

With Awk, the variable FNR is the number of the "record" (line, by default) in the current file, so you can simply compare it to 3 to print the third line of each input file:

awk 'FNR == 3' MiseqData/result2012/12*

A more optimized version for long files would skip to the next file on match, since you know there's only that one line where the condition is true:

awk 'FNR == 3 { print; nextfile }' MiseqData/result2012/12*

However, not all Awks support nextfile (but it is also not exclusive to GNU Awk).

A more portable variant using your head and tail solution would be a loop in the shell:

for f in MiseqData/result2012/12*; do head -n 3 "$f" | tail -n 1; done

Or with sed (without GNU extensions, i.e., the -s argument):

for f in MiseqData/result2012/12*; do sed '3q;d' "$f"; done

edit: As for the additional question of how to print the name of each file, you need to explicitly print it for each file yourself, e.g.,

awk 'FNR == 3 { print FILENAME ": " $0; nextfile }' MiseqData/result2012/12*

for f in MiseqData/result2012/12*; do
    echo -n `basename "$f"`': '
    head -n 3 "$f" | tail -n 1
done

for f in MiseqData/result2012/12*; do
    echo -n "$f: "
    sed '3q;d' "$f"
done
like image 166
Arkku Avatar answered Feb 03 '23 07:02

Arkku


With GNU sed:

sed -s -n '3p' MiseqData/result2012/12*

or shorter

sed -s '3!d' MiseqData/result2012/12*

From man sed:

-s: consider files as separate rather than as a single continuous long stream.

like image 30
Cyrus Avatar answered Feb 03 '23 08:02

Cyrus