如何用数组中的元素替换文件中的单词

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

我正在尝试将所有单词 "null" 替换为数组中的元素。问题是,在替换 "null" 的一个单词后,我想用数组中的下一个元素替换下一个 "null"。

我不太擅长bash,我觉得这是一个很基础的问题。

这是我目前的情况:

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

这不会替换 finalfile.csv 中的任何内容。

例如,如果文件有:

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

并且数组有 ["foo","bar"]

我希望它是:

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

在 Perl 中更容易,您可以直接在替换的替换部分增加索引:

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'

更新: 看来您已经使用样本输入更新了您的问题。如果空值被双引号括起来,它会变得更容易,因为不需要检查它们是否被行的逗号 beginning/end 包围。

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

逐行读取文件。如果一行包含 null,则使用 sed 将所有出现的 null 替换为相应的值,通过数组索引检索。

#!/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"

awk 解决方案:

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

可以用 bash 完成,即使每行有多个空值:

$ 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"