Как заменить слово из файла элементами в массиве - PullRequest
1 голос
/ 24 июня 2019

Я пытаюсь заменить все слова "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"...

Ответы [ 4 ]

2 голосов
/ 24 июня 2019

можно сделать с помощью 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"
2 голосов
/ 24 июня 2019

Это проще в 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'

Обновление: Кажется, вы обновили свой вопрос с помощью примера ввода. Если нулевые значения заключены в двойные кавычки, это становится еще проще, поскольку нет необходимости проверять, окружены ли они запятыми или началом / концом строки.

perl -pe 'BEGIN{ @cwe = qw( foo bar ) }
          s/"null"/"$cwe[$i++]"/g'
0 голосов
/ 24 июня 2019

Решение awk:

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>
0 голосов
/ 24 июня 2019

Читать файл построчно. Если строка содержит 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"
...