简体   繁体   中英

grep each line in a file

I have two files: one is a fairly long collection of names (names.txt), and another file (grades.csv) which is a huge file of names and the corresponding grades. I would like to iterate over each line in names.txt and extract that name in grades.csv with the entire matching line.

This is how a small sample names.txt looks like

"Dumbledore, Albus"
"Potter, Harry"
"Riddle, Tom

Here is the structure of a dummy grades.csv file

"Granger, Hermione", 96.65%, 9,10
"Mcgonagall, Minerva", 80.43%, 6,7
"Dumbledore, Albus", 100%, 8, 9
"Potter, James", 91%, 7,89
"Ravenclaw, Rowena", 32%, 4,56
"Potter, Harry", 34%, 56,67
"Riddle, Tom", 99%, 3,4

I'd like to extract each line of names.txt and search grades.csv to get this

"Dumbledore, Albus", 100%, 8, 9
"Potter Harry", 34%, 56,67
"Riddle Tom", 99%, 3,4

I know I would have to use grep/awk/sed for this (I am using a Linux environment) but I don't know how to use grep to loop over the lines in a file, since I am not very good at the bash command terminal. Any help appreciated!

I made some changes to your names.txt and grades.csv - some of the names are comma-separated and some aren't. I removed commas within quotes, so here are the new files:

22:46 $ cat names.txt 
"Dumbledore Albus"
"Potter Harry"
"Riddle Tom"

22:46 $ cat grades.csv 
"Granger Hermione", 96.65%, 9,10
"Mcgonagall Minerva", 80.43%, 6,7
"Dumbledore Albus", 100%, 8, 9
"Potter James", 91%, 7,89
"Ravenclaw Rowena", 32%, 4,56
"Potter Harry", 34%, 56,67
"Riddle Tom", 99%, 3,4

You can use grep with a file argument -f :

22:46 $ cat script.sh 
#!/bin/bash
names="/path/to/names.txt"
grades="/path/to/grades.csv"
grep -f <(tr ',' '\n' < "${names}") "${grades}"

This gives me the following output:

22:46 $ ./script.sh 
"Dumbledore Albus", 100%, 8, 9
"Potter Harry", 34%, 56,67
"Riddle Tom", 99%, 3,4

EDIT

Assuming the names.txt and grades.csv as a rule are formatted as "Lastname, Firstname" case-insensitively:

#!/bin/bash
names="/path/to/names.txt"
grades="/path/to/grades.csv"
grep -fi "${names}" "${grades}"

Try this:

  while read l; do grep -i "${l//\"/}" grades.csv; done < names.txt 

I tested it with bash on Ubuntu 14.04. The output:

$ while read l; do grep -i "${l//\"/}" grades.csv; done < names.txt 
"Dumbledore, Albus", 100%, 8, 9
"Potter, Harry", 34%, 56,67
"Riddle, Tom", 99%, 3,4

To answer your question literally:

for each in `cat names.txt`; do
    grep -q $each grades.csv
done

Just for novelty... If you didn't have commas in the name strings then you could also achieve this using the unix join operator.

man join

The join utility performs an equality join on the specified files and writes the result to the standard output.

If both inputs are sorted (in this example the files are re-written)

$ sort -b -o names.txt names.txt
$ sort -b -o grades.txt grades.txt

then you can do the following

$ join -t ',' grades.txt names.txt
"Dumbledore Albus", 100%, 8, 9
"Potter Harry", 34%, 56,67
"Riddle Tom", 99%, 3,4

The -t flag tells join to use the character as a field delimiter for both input and output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM