Замена значений переменных в определенной строке через awk / xargs - PullRequest
2 голосов
/ 28 мая 2020

Мы динамически генерируем строку в bash для вставки данных в oracle базу данных. Строка имеет вид

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

Здесь переменные $ 1, $ 2 ... являются динамическими c и могут go до 10

Теперь у нас есть данные в файле с тем же номером. столбцов данных, разделенных ':', поскольку в строке выше есть числовые c переменные ($ 1, $ 2 ..).

Задача состоит в том, чтобы заменить 1 доллар на 1-й столбец данных, 2 доллара на 2-й столбец и так далее. Это необходимо сделать для всех строк набора данных, и необходимо создать отдельный файл со строкой «вставить» в качестве основы и с замененными данными из файла.

Например, для данных образца

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','$1','$2','$3','$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','$1','$2','$3','$sdate' from dual ;
insert into tbl select '$jobid','$1','$2','$3','$sdate' from dual ;
insert into tbl select '$jobid','$1','$2','$3','$sdate' from dual ;

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

Написание маленького l oop и построчный вызов накладных расходов, так что не желайте этого делать. Есть идеи, как это можно сделать оптимальным образом?

1 Ответ

1 голос
/ 28 мая 2020

С помощью Awk для каждой записи замените каждый литерал $ n значением n-го поля в вашем шаблоне с помощью функции gsub и распечатайте результат.

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 ;
...