2

I am trying to read a csv file using shell script,using the following command.

cat file.csv | while read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done

When i run this command the first column in the file is not being read properly.

For Ex: If 1 st column contents are

number1,
number2,
number3,
number4,
(so on)

It outputs:

::::er1,
::::er2,
::::er3,
::::er4,

some characters are replaced by ':' this happens only for the first column contents. Where am i going wrong?

3
  • It looks to me like you have DOS-style CRLF line endings on a Unix machine. Commented Jul 1, 2016 at 6:18
  • @JonathanLeffler: Wasn't the not setting of IFS causing the issue here? Commented Jul 1, 2016 at 6:19
  • 1
    That too, but the colons at the start of the line indicate to me that there is a CR that's been kept as part of the data (because Unix lines end at the LF; the CR is just a character on the line). So, yes — IFS is probably part of the trouble, but the data probably comes from Windows, or travelled via a Windows machine at some point. Commented Jul 1, 2016 at 6:21

1 Answer 1

5

The problem is due to most likely a couple of issues:-

  • You are reading the file without the IFS=,
  • Your csv file might likely have carriage returns(\r) which could mangle how read command processes the input stream.

To remove the carriage returns(\r) use tr -d '\r' < oldFile.csv > newFile.csv and in the new file do the parsing as mentioned below.

Without setting the Internal Field Separator (IFS=","), while reading from the input stream read doesn't know where to delimit your words. Add the same in the command as below.

cat file.csv | while IFS="," read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done

You can see it working as below. I have the contents of the file.csv as follows.

$ cat file.csv
abc,def,ghi,ijk,lmn,opz
1,2,3,4,5,6

$ cat file.csv | while IFS="," read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done
abc:def:ghi:ijk:lmn:opz
1:2:3:4:5:6

More over using cat and looping it over it is not recommended and bash enthusiasts often call it as UUOC - Useless Use Of Cat

You can avoid this by doing

#!/bin/bash

while IFS="," read -r a b c d e f;
do
    echo "$a:$b:$c:$d:$e:$f"
done < file.csv
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much @inian for the detailed explanation, by including IFS=',' solved my issue.
i upvoted it, but it is not publicly visible cos i still don't have the minimum reputations.

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.