2016-06-10 2 views
0

Я пытаюсь изменить числа в столбцах 2, 3 и 4 файла. Чтобы сделать это, я следующий сценарийescaping в awk и bash script

for i in 0.8 0.9 1 1.1 1.2; do 
original=10.9398135077 
fraction=`bc <<< "$i*$original"` 
convert=0.529177 
awk '{printf "%-2s %10.5f %10.5f %10.5f\n", $1, ($2*"\$fraction"*"\$convert"), ($3*"\$fraction"*"\$convert"), ($4*"\$fraction"*"\$convert")}' temp2_${i}.txt > coord_${i}.txt 
done 

и мой temp2_0.8.txt выглядит следующим образом:

Cu  -0.000000000 0.000000000 -0.000000000 
Cu  0.500000000 -0.000000000 0.500000000 
Cu  0.000000000 0.500000000 0.500000000 
Cu  0.500000000 0.500000000 0.000000000 
S  0.398420013 0.398420013 0.398420013 
S  0.898420013 0.398420013 0.101579987 
S  0.398420013 0.101579987 0.898420013 
S  0.101579987 0.898420013 0.398420013 
S  0.601579987 0.601579987 0.601579987 
S  0.898420013 0.101579987 0.601579987 
S  0.101579987 0.601579987 0.898420013 
S  0.601579987 0.898420013 0.101579987 

Но если я исполню мой сценарий, я получаю сообщение:

awk: warning: escape sequence `\$' treated as plain `$' 

И я получаю 0.00000 во всех моих конвертируемых файлах. Кажется, мне не удалось избежать ключевых слов в awk .... как я могу умножить «фракцию» и «преобразовать» в столбцы номер 2, 3 и 4 с awk правильно?

Добавить :) Я \ $ фракции вместо «\ $ фракции», но это дает мне ошибку «обратный слэш не последний символ в строке»

+2

Внутри одинарных кавычек оболочка игнорирует доллары и обратную косую черту - интересны только одинарные кавычки. Следовательно, скрипт 'awk' неправильно вычисляет значения. Используйте '-v variable =" $ value "' для передачи переменных оболочки в скрипт. Зачем беспокоиться о 'bc'? 'awk' может многократно размножаться. –

+0

@JonathanLeffler Вау, спасибо, -v работает ~! Это намного проще, чем я ожидал. Причина, по которой я использовал bc, заключалась в умножении значений $ i в сценарии bash, чтобы использовать это в другой части скрипта. Но я думаю, что ваша идея тоже прекрасна :) Спасибо – exsonic01

ответ

3

Внутри одиночных кавычек, оболочка игнорирует доллары, обратные слэши, двойные кавычки, back-ticks - интересны только одинарные кавычки. Следовательно, сценарий awk ошибочно принимает значения. Используйте -v variable="$value", чтобы передать переменные оболочки скрипту. Зачем беспокоиться bc? awk может многократно размножаться.

original=10.9398135077 
convert=0.529177 
for i in 0.8 0.9 1 1.1 1.2 
do 
    awk -v org="$original" -v factor="$i" -v conv="$convert" \ 
     'BEGIN { multiplier = factor * original * convert } 
     { printf "%-2s %10.5f %10.5f %10.5f\n", $1, 
        ($2 * multiplier), 
        ($3 * multiplier), 
        ($4 * multiplier) }' temp2_${i}.txt > coord_${i}.txt 
done 
+0

Большое вам спасибо! – exsonic01

0

Вам не нужен цикл оболочки для этого:

awk ' 
BEGIN { 
    original = 10.9398135077 
    convert = 0.529177 
    split("0.8 0.9 1 1.1 1.2", factors) 
    for (i in factors) { 
     ARGV[i] = "temp2_"i".txt" 
     outfiles[i] = "coord_"i".txt" 
     multipliers[i] = factors[i] * original * convert 
     ARGC++ 
    } 
} 
{ 
    printf "%-2s %10.5f %10.5f %10.5f\n", $1, 
     $2 * multipliers[ARGIND], 
     $3 * multipliers[ARGIND], 
     $4 * multipliers[ARGIND] > outfiles[ARGIND] 
} 
' 

Если вы не используете GNU AWK затем добавить FNR==1{ARGIND++} заявление после раздела BEGIN{...}.