通过 awk / xargs 替换定义字符串中的变量值

Replacing variable values in defined string through awk / xargs

我们在bash中动态生成一个字符串,用于将数据插入到oracle数据库中。字符串就像

> echo $str1
insert into tbl select '$jobid','','','','$sdate' from dual ; 

这里变量 $1,$2 ... 是动态的,最多可以达到 10

现在我们在一个文件中拥有与上面字符串中的数字变量 ($1,$2..) 相同数量的“:”分隔数据列的数据。

这里的挑战是将 $1 替换为第一列数据,将 $2 替换为第二列,依此类推。这需要对数据集的所有行完成,并且需要以 "insert" 字符串作为基础并使用文件中的替换数据生成一个单独的文件。

例如样本数据

cat test.dat
ONLINE:odr1_redo_06a.log:NO
ONLINE:odr1_redo_06b.log:NO
ONLINE:odr1_redo_05a.log:NO

and the string is 
echo $str1
insert into tbl select '$jobid','','','','$sdate' from dual ;

要求的输出应该是

insert into tbl select '$jobid','ONLINE','odr1_redo_06a.log','NO','$sdate' from dual ;
insert into tbl select '$jobid','ONLINE','odr1_redo_06b.log','NO','$sdate' from dual ;
insert into tbl select '$jobid','ONLINE','odr1_redo_05a.log','NO','$sdate' from dual ;

尝试在 awk 中使用字符串作为外部变量。运气不好

cat test.dat | awk -F: -v var="$str1" '{print var}'
insert into tbl select '$jobid','','','','$sdate' from dual ;
insert into tbl select '$jobid','','','','$sdate' from dual ;
insert into tbl select '$jobid','','','','$sdate' from dual ;

or xargs
sed 's/:/ /g' test.dat | xargs -n3 bash -c "echo $str1"
insert into tbl select $jobid,,,,$sdate from dual
insert into tbl select $jobid,,,,$sdate from dual
insert into tbl select $jobid,,,,$sdate from dual

编写一个小循环并逐行调用会产生开销,所以不要这样做。知道如何以最佳方式做到这一点吗?

使用 Awk,对于每条记录,通过 gsub 函数将每个文字 $n 替换为模板中第 n 个字段的值并打印结果。

awk -F: -v tmpl="$str1" '{
  out = tmpl
  for (i=1; i<=NF; i++)
    gsub(("\$" i), $i, out)
  print out
}' file

概念验证:

$ str1="insert into tbl select '$jobid','$1','$2','$3','$sdate' from dual ;"
$
$ awk -F: -v tmpl="$str1" '{
>   out = tmpl
>   for (i=1; i<=NF; i++)
>     gsub(("\$" i), $i, out)
>   print out
> }' file
insert into tbl select '$jobid','ONLINE','odr1_redo_06a.log','NO','$sdate' from dual ;
insert into tbl select '$jobid','ONLINE','odr1_redo_06b.log','NO','$sdate' from dual ;
insert into tbl select '$jobid','ONLINE','odr1_redo_05a.log','NO','$sdate' from dual ;