2015-09-07 2 views
1

У меня есть файл в списке, как это:Modify через арифметических операций с плавающей точкой (положительные и отрицательные) в файле

-180.0564 
-179.0857 
178.4739 

мне нужно просмотреть весь файл и изменить только положительный (или отрицательный) значения, вычитающие целое число, равное 100 или в моем случае 360. Я разрабатываю этот код в Интернете, и я использую команду bc для плавающих операций.

Проблема в том, что теперь все отрицательные значения меняются, а не положительные, и я не могу понять, почему.

Вот код:

#!/bin/bash 

FILE=$1 

while read line;do 

if [ $(echo $line '>' 0.0 |bc -l) ]; then 

    line=$(echo "$line-360" |bc) 
    echo $line 

    else 

    echo $line 
fi 

done < $FILE 

ответ

0

Для любой задачи с участием технологических линий, это стоит рассматривать, используя AWK:

awk '{ print ($0 > 0 ? $0 - 360 : $0) }' "$file" 

Этот код заменяет весь while read цикл. В awk $0 относится к содержимому каждой строки. Логика такая же, как и в вашем коде: если строка больше 0, то вычитайте 360, иначе оставьте ее как есть.

Более короткий способ написать то же самое, используя AWK бы это:

awk '$0 > 0 { $0 -= 360 }1' "$file" 

Структура программы AWK является condition { action }, поэтому логика такая же, как и выше. Эта версия использует общую сокращенную версию 1, которая является самым коротким условием, которое всегда верно. Действие по умолчанию: { print }, которое печатает всю строку.

Любой из этих вариантов будет быстрее, поскольку они не вызывают внешние процессы и потому что awk быстрее, чем while read в любом случае. Что еще более важно, они также короче и легче читать.

Обратите внимание, что я использую $file, а не $FILE, поскольку, как правило, следует избегать имен переменных в верхнем регистре.

+0

Спасибо за скрипт, я также думаю, что awk проще, но у меня все еще есть эта ошибка 'awk: linea com.:1: {print line> 0? line - 360: line} awk: linea com.:1:^синтаксическая ошибка awk: linea com.:1: {print line> 0? line - 360: line} awk: linea com.:1:^синтаксическая ошибка' Я запускаю непосредственно строку, помещающую мое имя файла в конец, а не «$ FILE», правильно ли это? – user2710445

+0

Извините, мой код был полностью неправильным! Я обновил свой ответ. –

+0

@ user2710445 да, вы можете вызывать awk, передавая имя файла непосредственно из интерактивной оболочки, без необходимости в переменной. –

0

Это потому, что [] (на самом деле программирования test) предназначен для проверки - код возврата к нулю, если программа завершается успешно.

$ [ 0 ] && echo ok || echo err 
ok 

Что касается ваших вычислений, я бы избавиться от одного bc вызова с по модулю.

$ while read line; do bc <<< "($line-360)%360"; done < $FILE 
-180.0564 
-179.0857 
-181.5261 
+0

Большое спасибо за решение, отлично работает. – user2710445