Joe
Joe

Reputation: 1432

CSV - Grep a particular pattern, print first match and the first line of that file

I have multiple CSV files

> File 1
name,age,city
john,30,NY
cassey,25,SF
nick,25,DC

> File 2
attended,days
math,30
phy,25
che,25

> File 3
days, weeks
30, 4
20, 5

I want to search for a entry and when I get it, I want to stop at the first entry. However, I also want to print the first line of the file, as it is a CSV, it will help me with the name of the columns

If I search for 25, my desired output is

File 1:
  name,age,city
  cassey,25,SF
File 2:
  attended,days
  phy,25

With the following code, I'm able to print

# grep -m 1 25 * -rn
cassey,25,SF
phy,25

How to pipe the grep output to sed or another utility so that I can print the first column and the matching column in the output.

Upvotes: 0

Views: 1896

Answers (2)

fedorqui
fedorqui

Reputation: 290135

You can use awk for this:

$ awk 'NR==1{print} NR>1 && /25/ {print; exit}' file
name,age,city
cassey,25,SF

That is, when the NR (number of record, here number of line) is 1, print it. From that moment on, whenever a line matches the pattern, print it and exit.


To check in all files:

for file in *
do
   echo "$file"
   awk 'NR==1{print} NR>1 && /25/ {print; exit}' $file
done

Where * can be a file pattern like file*. In that case, it will loop through all the files whose name starts with file.


To just print those file names which match, do:

for file in *
do
   do grep -q 25 "$file" && echo "$file" && awk 'NR==1{print} NR>1 && /25/ {print; exit}' $file
done

grep -q returns true if there is a match. In that case, it proceeds and prints the file name and the line.

Upvotes: 4

aragaer
aragaer

Reputation: 17858

You can just use sed instead of grep. Use ls and xargs to proces many files:

ls file* | xargs -n1 sed -n '1{x;d}; /25/{x;p;x;p;q}'

The reason for all 'x;p' is to not print the first line if pattern is not found in the file.

file1:

name,age,city
cassey,25,SF

file2:

attended,days
phy,25
at,25

file3:

attended,days
phy,26

Result:

$ ls file* | xargs -n1 sed -n '1{x;d}; /25/{x;p;x;p;q}'
name,age,city
cassey,25,SF
attended,days
phy,25

Edit: Printing the file name - now a proper bash loop:

$ for i in `grep -l 25 file*` ; do echo $i; head -n1 $i; grep -m1 25 $i; done
file1
  name,age,city
  cassey,25,SF
file2
  attended,days
  phy,25

Upvotes: 1

Related Questions