2016-01-26 2 views
1

Я немного новичок в использовании awk. Моя цель состоит в том, чтобы создать функцию Баша формы:Умножение Awk дает ноль

myfunction file column value 

, который принимает данный номер столбца в файле, умножает его значение и перезаписывает файл. На данный момент я написал следующее:

function multiply_column { 
file=$1 
column=$2 
value=$3 
awk -F" " '{print $col*mul}' col=$column mul=$value $file 
} 

Мой файл выглядит следующим образом:

0.400000E+15 0.168933E+00 -0.180294E-44 0.168933E+00 
    0.401000E+15 0.167689E+00 -0.181383E-44 0.167689E+00 
    0.402000E+15 0.166502E+00 -0.182475E-44 0.166502E+00 
    0.403000E+15 0.165371E+00 -0.183569E-44 0.165371E+00 
    0.404000E+15 0.164298E+00 -0.184666E-44 0.164298E+00 
    0.405000E+15 0.163284E+00 -0.185766E-44 0.163284E+00 
    0.406000E+15 0.162328E+00 -0.186868E-44 0.162328E+00 
    0.407000E+15 0.161431E+00 -0.187972E-44 0.161431E+00 
    0.408000E+15 0.160593E+00 -0.189080E-44 0.160593E+00 
    0.409000E+15 0.159816E+00 -0.190189E-44 0.159816E+00 
    0.410000E+15 0.159099E+00 -0.191302E-44 0.159099E+00 
    0.411000E+15 0.158442E+00 -0.192416E-44 0.158442E+00 
    0.412000E+15 0.157847E+00 -0.193534E-44 0.157847E+00 
    0.413000E+15 0.157312E+00 -0.194653E-44 0.157312E+00 
    0.414000E+15 0.156840E+00 -0.195775E-44 0.156840E+00 
    0.415000E+15 0.156429E+00 -0.196899E-44 0.156429E+00 
    0.416000E+15 0.156081E+00 -0.198026E-44 0.156081E+00 
    0.417000E+15 0.155796E+00 -0.199154E-44 0.155796E+00 
    0.418000E+15 0.155573E+00 -0.200285E-44 0.155573E+00 
    0.419000E+15 0.155413E+00 -0.201418E-44 0.155413E+00 
    0.420000E+15 0.155318E+00 -0.202554E-44 0.155318E+00 
    0.421000E+15 0.155285E+00 -0.203691E-44 0.155285E+00 
    0.422000E+15 0.155318E+00 -0.204831E-44 0.155318E+00 
    0.423000E+15 0.155414E+00 -0.205973E-44 0.155414E+00 
    0.424000E+15 0.155575E+00 -0.207116E-44 0.155575E+00 
    0.425000E+15 0.155802E+00 -0.208262E-44 0.155802E+00 

мне удалось просто напечатать первый столбец, но когда я умножить его с моим значением, AWK дает мне 0 Я попробовал свою функцию с другими файлами, где данные были отформатированы по-разному, и она отлично работала. Я также попытался объединить его с bc, без каких-либо успехов.

Кто-нибудь видит, почему в этом случае awk дает 0?

Заранее благодарен!

######### EDIT

Я только что узнал, что, если мой файл данных использует запятые и не точки (т.е. 0,400000E + 15 вместо 0.400000E + 15), моя функция работает нормально. Так что-то, где-то, что-то настроено для понимания запятых как разделителя научной нотации вместо точек. Это звонит кому-нибудь?

+1

Хмм, отлично работает для меня ... –

+0

Я забыл упомянуть, что использую Mac OSX. Может ли это быть связано? – Scrimbibete

+0

Как вы называете функцию 'multiply_column' точно? Какие аргументы? – hek2mgl

ответ

4

Установите LC_ALL=C перед выполнением вашего сценария чтобы получить наиболее часто ожидаемое поведение для этой и других проблем, зависящих от языка. См. http://www.gnu.org/software/gawk/manual/gawk.html#Locales. Также не бессмысленно устанавливать FS на значение по умолчанию, цитируйте свои переменные оболочки (google, если вы не знаете почему), и исправляете то, как вы устанавливаете переменные, чтобы использовать форму, которая дает наиболее интуитивные результаты (см http://cfajohnson.com/shell/cus-faq-2.html#Q24):

LC_ALL=C awk -v col="$column" -v mul="$value" '{print $col*mul}' "$file" 

Читать книгу программирования Эффективное Awk, 4-е издание, Арнольд Роббинс.

+0

Какая переменная из переменных 'LC_ *' использует 'awk' для этого? У меня есть ["смешанная" локаль] (http://pastebin.com/H8VHXVbx), где работает 'LC_NUMERIC = de_DE.UTF-8' и скрипт из вопроса. – hek2mgl

+0

@ hek2mgl Вы используете GNU awk? – jlliagre

+0

@ hek2mgl, если я понимаю ваш вопрос - awk не использует их для этого, потому что по умолчанию '.' является десятичной точкой, если не заполнено« LC_NUMERIC »И' --use-lc-numeric' задано в команде линия. Это так gawk по умолчанию ведет себя по желанию для обычного случая людей в локали, где ',' определяется как десятичная точка для своей локали, но их входные данные используют '.' (Что, по-видимому, является операцией OPs, но он не является используя gawk, или он поступил бы по желанию). –

2

Существует несоответствие между языком, используемым для создания файла данных, и текущего.

Например, французский язык и аналогичные используют запятую в качестве своего десятичного разделителя, в то время как точка является наиболее широко используемой, а также является стандартом POSIX.

Если вы хотите для запятые, чтобы быть принята в качестве десятичных разделителей, вы можете обойти эту проблему так:

LC_NUMERIC=fr_FR.UTF-8 awk '{print $col*mul}' col="$column" mul="$value" "$file" 

Обратите внимание, что это не будет работать как с GNU awk, который не чтит числовой языковой настройке по умолчанию. Вам нужно будет использовать флаг --use-lc-numeric для переопределения.

В качестве альтернативы, если вы хотите для точек, которые будут приняты в качестве десятичных разделителей, но текущая локаль использует запятые, и вы не используете GNU AWK, вы можете запустить:

LC_NUMERIC=C awk '{print $col*mul}' col="$column" mul="$value" "$file" 
+1

Вы можете проверить свой язык с помощью команды 'locale'. –

+0

Моя локаль - это 'LC_NUMERIC = de_DE.UTF-8', которая также использует' '' как десятичный разделитель. Меня устраивает. – hek2mgl

+0

@ hek2mgl Что работает для вас? Опубликованный файл данных? Фактический файл данных? С GNU awk? Unix awk? – jlliagre

Смежные вопросы