如何用数组中的元素替换文件中的单词
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"
我正在尝试将所有单词 "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"