Parse CSV in Bash and Assign Variables

Parse CSV in bash and assign variables

Try a loop:

while IFS=, read dn mac partition
do
echo "Do something with $dn $mac and $partition"
done < file

To select a record you could use a case statement:

P2=123
while IFS=, read dn mac partition
do
case $dn in
($P2) echo echo "Do something with $dn $mac and $partition" ;;
(*) echo "Do nothing" ;;
esac
done < file

shell parse csv file, assign fields to variable and print it in multiple columns

awk is certainly the correct tool to use for this, but you can also do:

curl http://example.com/1.txt |
while IFS=, read ip type name rest; do
echo $ip $type $name
done

The variables will lose their value after the while loop finishes, since it is in a sub-shell.

How to parse a CSV file in Bash?

You need to use IFS instead of -d:

while IFS=, read -r col1 col2
do
echo "I got:$col1|$col2"
done < myfile.csv

Note that for general purpose CSV parsing you should use a specialized tool which can handle quoted fields with internal commas, among other issues that Bash can't handle by itself. Examples of such tools are cvstool and csvkit.

Bash: Parse CSV and edit cell values

See Why is using a shell loop to process text considered bad practice?

As question is tagged linux, assuming GNU sed is available. And also that the input is actually csv, not space/tab separated

$ cat ip.csv 
ID,Location,Way,Day,DayTime,NightTime,StandNo
1,abc,Up,mon,6.00,18.00,6
2,xyz,down,TUE,2.32,5.23,4

$ sed '2,$ {s/[^,]*/\L\u&/4; s/[^,]*/\U&/3; s/[^,]*/\U&/2}' ip.csv
ID,Location,Way,Day,DayTime,NightTime,StandNo
1,ABC,UP,Mon,6.00,18.00,6
2,XYZ,DOWN,Tue,2.32,5.23,4
  • 2,$ to process input from 2nd line to end of file
  • s/[^,]*/\L\u&/4 capitalize only first letter of 4th field
  • s/[^,]*/\U&/3 capitalize all letters in 3rd field
  • s/[^,]*/\U&/2 capitalize all letters in 2nd field

If the fields themselves can contain , within double quotes and so on, use perl, python, etc which has csv modules

Bash Read CSV value from Variable in Bash

"192.168.1.1,192.168.100.1"

Here is your issue. The problem is that when the while loop is reading, after the first iteration there is no more commas so it hits the end and quits. "192.168.1.1,192.168.100.1," should show the way you are intending.

As other's have suggested in the comments, I would go with a for loop myself, but to with closet to how you were trying to implement it, this would work for you:

IP_PING="192.168.1.1,192.168.1.2,192.168.1.3"
while read -r ip1 ; do
ping -c 4 "$ip1" >/dev/null
if [ $? -ne 0 ]; then
echo "Ping fail"
else
echo "Ping success"
fi
done < <(echo $IP_PING |tr ',' '\n')

< <(echo $IP_PING |tr ',' '\n') is process substitution. To put it simply it will "pipe" the output into the while loop. The difference from a normal pipe being that it creates one less process; the actual pipe creates a process itself.

Using process substitution will also keep the while loop in the current environment as well. (vs a while loop usually takes a 'snapshot' of the env and uses that during the loop, then it disappears when the loop ends) Meaning, with process substitution, that processes in the while loop will be able to see changes in env variables of the parent while it is looping, AND variables assigned within the loop will also still be available in the parent after it ends.

Read input from a csv and append that values to variable using shell script

I don't see anything in your code that would cause your script to only show the last value.

This may be an illusion: is your dir.csv file CRLF-delimited? (DOS/Windows format) If so, remove the CR that ends each line with a utility like dos2unix or a command like tr -d '\r'.

Some notes though:

  • In Dir+="Dir,$line", the string Dir should probably be removed (Dir+=",$line").
  • You probably want to get rid off the initial comma: Dir=${Dir#,}.
  • All this can be simplified with the single command below:
Dir=$(paste -s -d, dir.csv)

... or, with CRLF line-endings:

Dir=$(tr -d '\r' < dir.csv | paste -s -d,)

How to parse a CSV in a Bash script?

First prototype using plain old grep and cut:

grep "${VALUE}" inputfile.csv | cut -d, -f"${INDEX}"

If that's fast enough and gives the proper output, you're done.



Related Topics



Leave a reply



Submit