Let's say I have the following CSV file (sample.csv)
filepath1
filepath1,filepath2
filepath1,filepath2,filepath3
filepath1,filepath2,filepath3,filepath4
filepath1,filepath2
And the program I need to use uses the following syntax:
program_im_using --file filepath1
But if multiple files are present, the syntax for input is:
program_im_using --file filepath1 --file filepath2
or
program_im_using --file filepath1 --file filepath2 --file filepath3
What I would do to paste the values from the CSV file would be something like this:
filepath_first=( $(awk -F "\"*,\"*" '{print $1}' $sample_csv) )
filepath_second=( $(awk -F "\"*,\"*" '{print $2}' $sample_csv) )
for i in "${!filenames[@]}"; do
program_im_using --file "${filepath_first[i]}" --file "${filepath_second[i]}"
done
My example of what I'm doing only works if I have exactly 2 columns of values in every row. How can I generalize in a way such that if I have one column, I get:
program_im_using --file filepath1
But if I have two
program_im_using --file filepath1 --file filepath2
etc?
For a variable number of args one common approach is to store the args in an array, eg:
$ args=(--file filepath1 --file filepath2)
$ typeset -p args
declare -a args=([0]="--file" [1]="filepath1" [2]="--file" [3]="filepath2")
A sample script to list input args:
$ cat program_im_using
#!/bin/bash
n=1
for i in "$@"; do echo "arg #$n:$i:";((n++)); done
We can then feed these args to the program like such:
$ ./program_im_using "${args[@]}"
arg #1 :--file:
arg #2 :filepath1:
arg #3 :--file:
arg #4 :filepath2:
Sample input file:
$ cat sample.csv
filepath1
filepath1,filepath2
filepath1,filepath2,filepath3
/a/b/c.txt,/d/e/f/g.txt,/h.txt
Using sed
to reformat our csv lines:
$ sed 's/^/--file /; s/,/ --file /g' sample.csv
--file filepath1
--file filepath1 --file filepath2
--file filepath1 --file filepath2 --file filepath3
--file /a/b/c.txt --file /d/e/f/g.txt --file /h.txt
Feeding the sed
results to a bash/while-read
loop:
while read -ra args
do
printf "\n####### ${args[*]}\n"
./program_im_using "${args[@]}"
done < <(sed 's/^/--file /; s/,/ --file /g' sample.csv)
NOTES:
bash
This generates:
####### --file filepath1
arg #1 :--file:
arg #2 :filepath1:
####### --file filepath1 --file filepath2
arg #1 :--file:
arg #2 :filepath1:
arg #3 :--file:
arg #4 :filepath2:
####### --file filepath1 --file filepath2 --file filepath3
arg #1 :--file:
arg #2 :filepath1:
arg #3 :--file:
arg #4 :filepath2:
arg #5 :--file:
arg #6 :filepath3:
####### --file /a/b/c.txt --file /d/e/f/g.txt --file /h.txt
arg #1 :--file:
arg #2 :/a/b/c.txt:
arg #3 :--file:
arg #4 :/d/e/f/g.txt:
arg #5 :--file:
arg #6 :/h.txt: