2015-05-24 1 views
2

У меня есть команда вставки в моем скрипте. Но это не дает желаемого результата. мой файл данныхКак использовать команду вставки рекурсивно в сценарии оболочки

file.txt 
1 
3 
5 
4 

мой сценарий оболочки

f1=file.txt 
for j in 1..12 
do 
awk '{printf ("%.1f\n", $1+'$j');}' $f1 > $j_$f1 
paste $j_$f1 > ofile.txt # ofile.txt is a new empty file 
done 

Этот сценарий дает результат, как

ofile.txt 
2 
4 
6 
5 
3 
5 
7 
6 
. 
. 

Мой желаемый результат, как

ofile.txt 
2 3 4 5 6 ... 13 
4 5 6 7 8 ... 15 
6 7 8 9 10 .. 17 
5 6 7 8 9 ... 16 

Я также хочу сделать для следующий сценарий

bonus_company1=10 
bonus_company2=25 
bonus_company3=50 
declare var=("company1" "company2" "company3") 
for k in var{[@]} 
do for j in jan..dec 
    do if [ $j == "jan" ] || [ $j == "may" ] || [ $j == "sep" ]; then 
     awk '{printf ("%.1f\n", $1+ '$bonus_$k');}' $f1 > $k_$j_$f1 
     elif [ $j -ne "jan" ] && [ $j -ne "may" ] && [ $j -ne "sep" ]; then 
     awk '{printf ("%.1f\n", $1+5);}' $f1 > $k_$j_$f1 
     fi 
     paste $k_$j_$f1 > $k.txt # $k.txt is a new empty file 
    done 
done 

поэтому я получу 3 разных файла для трех компаний. например

company1.txt 
11 6 6 6 11 ..... 
13 8 8 8 11 ..... 
15 10 10 10 15 ..... 
14 9 9 9 14 ..... 

ответ

4

Я предложил бы делать все это в AWK, а не с помощью цикла оболочки:

awk '{for (i=1; i<=12; ++i) printf "%d%s", $1+i, (i<12?FS:RS)}' "$f1" > output 

Этот цикл выполняется для каждой строки файла и выводит все столбцы, спасая необходимо использовать другой инструмент, такой как paste. Тернарный оператор используется для вывода пробела (FS) между каждым столбцом и новой строкой (RS) в конце строки.


Для второй части вашего вопроса вы все равно можете выполнить большую часть работы в awk.

declare -A companies 
companies=([company1]=10 [company2]=25 [company3]=50) 
for c in "${companies[@]}"; do 
    awk -v bonus="${companies[c]}" '{for (i=1; i<=12; ++i) 
     printf "%d%s", $i+(i==1||i==5||i==9?bonus:5), (i<12?FS:RS)}' "$f1" > "$c.txt" 
done 

Я создал ассоциативный массив, содержащий имя каждой компании и их бонус. Цикл проходит через каждую компанию в массиве, передавая бонус awk как переменную (обратите внимание, что я делаю это с использованием -v, а не с помощью конкатенации строк). Цикл идет от 1 до 12, добавляя бонус на месяцы 1, 5 и 9 или 5 в противном случае. Название файла (ключ массива оболочки) используется для выходного файла.

+0

Это не совсем понятно, что вы имеете в виду, вы должны изменить свой вопрос, чтобы объяснить, что именно вы пытаетесь сделать. –

+0

Он отлично выглядит! Тогда можно сделать, когда мой j - это разные символы вместо чисел, например. для j в {разных названиях компаний}, и мои вычисления различны соответственно, например. если [conditon true]; затем awk '{printf "% s \ n", $ 1}. Я соответствующим образом отредактировал вопрос. – Roselover

+0

Я отредактировал свой ответ, чтобы показать, как вы могли бы ответить на вторую часть своего вопроса. Я предполагаю, что вы используете оболочку, которая поддерживает ассоциативные массивы (например, bash), отчасти потому, что вы использовали '==' для сравнения в вашей попытке. –

1

Я не могу понять, почему вы так сложны. Вы можете сделать это в более простой способ:

для второй один:

for k in var{[@]} 
do awk '{printf("%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n", $1+"$bonus_$k", $1+5, $1+5, $1+5, $1+"$bonus_$k", $1+5, $1+5, $1+5, $1+"$bonus_$k", $1+5, $1+5, $1+5);}' file.txt > $k_file.txt 
done 
+0

Спасибо за ваш ответ @Skylark. Но это слишком ручно. – Roselover