LINUX.ORG.RU

[Bash][Awk][кривые руки] Переменная, которая хранит команду

 , ,


0

2

Есть скрипт:

#!/bin/bash

start=1960937
shift=100000
while (($start <= 248519532))
do
run_str="awk 'BEGIN {FS=\";\";start = ${start}; shift = ${shift}; count = 0} {if ((\$2 >= start) && (\$2 < (start + shift - 1))) count++} END {print count}' db.txt"
echo `"${run_str}"`
start=$(($start+$shift))
done

Как грамотно «выполнить» содержимое переменной run_str?

Всё, что я получил «команда не найдена» и проблемы из-за одинарной кавычки.

Если выполнить:

awk 'BEGIN {FS=";";start = 1960937; shift = 10000; count = 0} {if (($2 >= start) && ($2 < (start + shift - 1))) count++} END {print count}' db.txt
то проблем никаких.

Как грамотно месить код bash с awk? Советы, рецепты...

команду в `` помести. run_str=`awk 'BEGIN {FS=\";\";start = ${start}; shift = ${shift}; count = 0} {if ((\$2 >= start) && (\$2 < (start + shift - 1))) count++} END {print count}' db.txt`

thexf
()

DarkAmateur> Как грамотно месить код bash с awk? Советы, рецепты...

Не загонять команды в переменные

sdio ★★★★★
()
#!/bin/bash

start=1960937
shift=100000
while (($start <= 248519532))
do
run_str="awk 'BEGIN {FS=\";\";start = ${start}; shift = ${shift}; count = 0} {if ((\$2 >= start) && (\$2 < (start + shift - 1))) count++} END {print count}' db.txt"
eval ${run_str}
start=$(($start+$shift))
done

Не?

geekless ★★
()
Ответ на: комментарий от thexf

я где-то читал в интернетах, что лучше $(something) чем `something`

anonymous
()
Ответ на: комментарий от thexf

Теперь не работают подстановки. Получилось вот что:

#!/bin/bash

start=1960937
shift=100000
while (($start <= 248519532))
do
run_str=`awk 'BEGIN {FS=";";start = 1960937; shift = 100000; count = 0} {if ((\$2 >= start) && (\$2 < (start + shift - 1))) count++} END {print count, start, shift}' db.txt`
echo ${run_str}
start=$(($start+$shift))
done

DarkAmateur ★★★★
() автор топика

DarkAmateur>

 awk 'BEGIN {FS=\";\";start = ${start}; shift = ${shift}; count = 0} {if ((\$2 >= start) && (\$2 < (start + shift - 1))) count++} END {print count}' db.txt

Это может/должно быть записано так:

awk -F';' -v start=$start -v shift=$shift '$2 >= start && $2 < (start + shift - 1) {count++};   END {print count}' db.txt

sdio ★★★★★
()

До чего-же страшненький кадаврик у тебя. Не смог пройти мимо не перерисав по-людски:

#!/bin/awk -f

BEGIN {
  FS=";";
  start = 1960937;
  shift = 100000;
  finish = 248519532;
}
{
  if (($2 >= start) && ($2 <= 248519532+100000))
  {
    #print "index=" (int($2/shift)*shift)
    iindex=(int(($2-start)/shift)*shift)+start # группируем числа по индексам 1960937, 2060937, 2160937 и т.д.
    if (iindex in count)
      count[iindex]++;
    else
      count[iindex]=1;
  }
}
END {
  #for (i in count)
  #  printf("count[%s]=%s\n",i,count[i]);
  for (i=start;i<=finish;i+=shift)
  {
    #printf("count[%s]=%s\n",i,count[i]);
    print int(count[i]);
  }
}

Тестовый прогон:

┌[legolegs@battlehummer ~/programing/DarkAmateur] :)
└> time ./1.sh > sh.log

real    1m3.289s
user    0m54.865s
sys     0m3.908s
┌[legolegs@battlehummer ~/programing/DarkAmateur] :)
└> time ./1.awk < db.txt > awk.log

real    0m0.071s
user    0m0.054s
sys     0m0.004s
┌[legolegs@battlehummer ~/programing/DarkAmateur] :)
└> cmp awk.log sh.log 
┌[legolegs@battlehummer ~/programing/DarkAmateur] :)
└>

Ну и твой первоначальный вариант, слегка исправленный:

#!/bin/bash

start=1960937
shift=100000
while (($start <= 248519532))
do
run_str="
BEGIN {
FS=\";\";
start = ${start};
shift = ${shift};
count = 0;
}
{
if ((\$2 >= start) && (\$2 < (start + shift - 1)))
  count++;
}
END {
print count;
}"
awk "${run_str}" db.txt
start=$(($start+$shift))
done

Понятно, что тебе уже не надо, но может научишься чему.

legolegs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.