4

I'm trying to parse a set of csv files using bash shell script the files looks as below:

File1: /tmp/test.txt
key1,key1file.txt
key2,key2file.txt
key3,key3file.txt

Files: /tmp/inter/key1file.txt
abc,cdf,123,456

Files: /tmp/inter/key2file.txt
abc,cdf,123,456

Files: /tmp/inter/key3file.txt
abc,cdf,123,456

I've tried parsing these files using 2 while loops:

while IFS="," read keycol keyfile
do
    while IFS="," read keyval
     do
     echo "inside inner while loop"
     echo "$keycol|$keyval"
    done < "/tmp/inter/$keyfile"
done < /tmp/test.txt

and expecting this code to output

key1,abc
key1,cdf
key1,123
key1,456 and so on...

However, i'm not getting any output when i run this code which indicates the second loop is not being executed. Any pointers in the right direction would be of help. Thanks

3
  • You have /tmp/test.txt in one place and /tmp/test.csv in another. Is that it? Commented Jul 11, 2017 at 12:04
  • Add a printout to the outer loop. Is that loop even running? Commented Jul 11, 2017 at 12:05
  • In general, read is not up to the task of parsing a CSV file; it cannot accommodate commas that are escaped to be part of a field, rather than separating two fields. Use a language that has a proper CSV parser available. Commented Jul 11, 2017 at 13:17

1 Answer 1

4

You are not properly splitting by , in your second loop. read generally splits by IFS, and assigns values to variables, one field per variable, and the remaining goes into the last variable provided. But if you provide only one variable, everything just gets stored there.

Instead, let read split by , into an array, then loop over values in that array, like this:

#!/bin/bash
while IFS="," read keycol keyfile; do
    while IFS="," read -a values; do
        for val in "${values[@]}"; do
            echo "$keycol,$val"
        done
    done < "/tmp/inter/$keyfile"
done < /tmp/test.txt

You'll get:

key1,abc
key1,cdf
key1,123
key1,456
key2,abc
key2,cdf
key2,123
key2,456
key3,abc
key3,cdf
key3,123
key3,456
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks randomir, your suggestion worked. For some reason the line feed was missing in the files under inter folder, i believe that caused the inner loop not work.
You're welcome. The problem was in inner loop read splitting. Each line read got from inter/$keyfile it "split" it into exactly one variable. The key was to use -a, to split the line into multiple values and store them inside an bash array.
Great answer!. How is IFS used of nested for loop?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.