2

I have a csv file and I need to compare the value in 4th column of 2nd row with a string.

Sample csv file:

Col1,Col2,Col3,Col4
Val1,Val2,Val3,ValNeeded

I'm using the below code to perform this,

varcsv=`sed '2q;d' file.csv | cut -d',' -f4 | tr -d ' '`

myvar=ValNeeded

if [ "$varcsv" = "$myvar" ]; then
    echo "true"
else
    echo "false"
fi

Output of this code is false and the length of varcsv is 10 (even the length is incorrect).

Please let me know where the change is required.

5
  • If your cat´ version supports the -v` option, please share the output of cat -v file.csv
    – Philippos
    Commented Oct 22, 2021 at 10:52
  • Who is deleting comments and why? Commented Oct 22, 2021 at 11:22
  • 1
    convert your .csv file from windows to unix text file format with fromdos. or if you don't have that installed, you can use perl -i -p -e 's/\r\n/\n/' filename.csv
    – cas
    Commented Oct 22, 2021 at 12:03
  • Philippos, I'm seeing ^M at the end
    – nishitha.m
    Commented Oct 22, 2021 at 12:39
  • Cas, the perl worked. Thanks
    – nishitha.m
    Commented Oct 22, 2021 at 16:55

2 Answers 2

1

While I posted my answer as a comment and comments were removed, let's give it another shot:

The way you are approaching it is OK but can be improved in such a way that you won't need the dependency on too many external binaries. For example, to solve your issue you can use awk as follows:

awk -F, -vmyvar="ValNeeded" 'NR==2 { if ($4 == myvar) print "match"; else print "No match"}'  file.csv

If you want to keep your code but rewrite it slightly it'd look like this:

#!/bin/bash

varcsv=$(awk -F, 'NR==2 { print $NF }' file.csv)
myvar=ValNeeded
if [[ $varcsv == "$myvar" ]]; then
    echo "true"
else
    echo "false"
fi

The $NF there gets the last field in the record.

As it was already mentioned by Philippos, your file contains MSDOS line endings, a.k.a CR/LF. You can check those in different ways using, cat, sed, od and many other tools but let's keep it simple and use cat and sed in this case:

cat -vEt file.csv or sed -n l file.csv

This will return something like:

Val1,Val2,Val3,SomeVar^M$
Val1,Val2,Val3,ValNeeded^M$
Val1,Val2,Val3,Ignorevar^M$
$

To remove these ^M$ charachters all together, you can use some utils. For example: dos2unix file.csv. There are other ways to do it from within the editor but that requires more effort.

Once you've converted the file you should be good.

0

This is a typical problem with files that have MSDOS line endings (carriage return + line feed). The carriage return is invisible, but will be part of the string to compare.

You already discovered the length is wrong and I suppose your tr -d ' ' was intended to remove a trailing space, but the problem was not a whitespace. Just add a carriage return to your tr argument (enter it by typing ctrlV followed by Return. It will show as tr -d ' ^M'.

5
  • Philippos, this is not helpong either.
    – nishitha.m
    Commented Oct 22, 2021 at 10:25
  • I had one more observation that if I try to append at the end of anything to the csv output, it's getting appensed at the start. Like: abc${varcsv}__def Output: __deflNeeded
    – nishitha.m
    Commented Oct 22, 2021 at 10:31
  • 1
    that's not anything being "appended at the start". That's the carriage return at the end of $varcsv returning the cursor to the beginning of the line when the string is printed, then continuing with __def. That's what CR does, it's what it's for, it's why it's called "Carriage Return". the name goes back to old mechanical typewriters and teletypes and the like.
    – cas
    Commented Oct 22, 2021 at 11:51
  • 1
    try piping the output into cat -A or cat -v or hexdump. you'll see the ^M in the middle of cat's output (or hex 0d in the case of hexdump).
    – cas
    Commented Oct 22, 2021 at 11:59
  • Yea I'm seeing ^M at the end
    – nishitha.m
    Commented Oct 22, 2021 at 12:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .