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.