EDK
EDK

Reputation: 35

How to replace a word from a file with elements in an array

I am trying to replace all the word "null" to elements in array. The problem is that after replacing one word of "null", I would like to replace the next "null" with next element in the array.

I am not very good with bash and I feel like this is quite a basic question.

Here is what I have so far:

for m in $(cat finalfile.csv)
do
    if [ "$m" = "null" ]
    then
        m=cwearray[$counter]
        let counter++
    fi
done

This doesn't replace anything in the finalfile.csv.

For example if the file has:

"value1","value2","null","value3"\n
"value1","value2","null","value3"...

and the array has ["foo","bar"]

I would like it to be:

"value1","value2","foo","value3"\n
"value1","value2","bar","value3"...

Upvotes: 1

Views: 313

Answers (4)

glenn jackman
glenn jackman

Reputation: 247162

can be done with bash, even with multiple nulls per line:

$ cat finalfile.csv
"value1","value2","null","null"
"value1","value2","null","value3"

$ cwearray=( foo bar baz )

$ idx=0

$ while read -r line; do 
    while [[ $line == *null* ]]; do 
      line=${line/null/${cwearray[idx++]}}
      # ...............^^^^^^^^^^^^^^^^^^
      # replace the _first_ "null" with the _next_ array element
    done
    echo "$line"
  done < finalfile.csv > updatedfinalfile.csv

$ cat updatedfinalfile.csv
"value1","value2","foo","bar"
"value1","value2","baz","value3"

Upvotes: 2

zwbetz
zwbetz

Reputation: 1100

Read the file line by line. If a line contains null, then use sed to replace all occurrences of null with the corresponding value, retrieved via array index.

#!/bin/bash

file="finalfile.csv"
counter=0

array=(
  "foo"
  "bar"
)

while read -r line; do
  item="${array[$counter]}"
  echo "$line" | sed "s/null/$item/g"
  ((counter++))
done < "$file"

Upvotes: 0

Corentin Limier
Corentin Limier

Reputation: 5016

An awk solution :

declare -a cwearray
cwearray=(foo bar)
awk -F, 'NR==FNR{repl[NR]=$0; next}{for(i=1;i<=NF;i++){if($i=="\"null\""){$i="\""repl[++counter]"\""}}}1' OFS="," <(for i in "${cwearray[@]}"; do echo "$i"; done) <file>

Upvotes: 0

choroba
choroba

Reputation: 242228

It's easier in Perl where you can increase the index directly in the replacement part of a substitution:

printf '%s\n' 1,2,3,null null,2,3,4 null,null,null,null \
| perl -pe 'BEGIN { @cwe = qw( A B C D E F ) }
            s/(?:^|(?<=,))null(?=,|$)/$cwe[$i++]/g'

Update: It seems you've updated your question with a sample input. If nulls are double quoted, it gets even easier, as there's no need to check whether they're surrounded with commas or beginning/end of the line.

perl -pe 'BEGIN{ @cwe = qw( foo bar ) }
          s/"null"/"$cwe[$i++]"/g'

Upvotes: 2

Related Questions