2015-08-24 3 views
0

[Ubuntu 14,04, GNU Awk 4.0.1]AWK числовая переменная рассматривается как строка

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

Я пробовал цикл For Loop, и теперь Loop Loop, обе страдают той же проблемой.

С файлом, который я обрабатываю, samples содержит значение 8092, а цикл останавливается на девятой итерации.

#!/usr/bin/awk -f 
BEGIN { 
    samples = 0; 
} 
{ 
    ... 
    samples = $24; 
} 
END { 
    i = 1; 
    while (i <= samples) { 
    if (i>samples) { print "This is the end.\n " i " is bigger than " samples;} 
    i++; 
    } 
} 

Я очень новичок в AWK и не понимаю, почему это происходит. Прочитав несколько руководств, у меня сложилось впечатление, что AWK может конвертировать между строками & числовые представления чисел по мере необходимости.

Может кто-нибудь помочь мне увидеть, что я сделал неправильно?

Решение Ответ был, как JNevill & Ghoti предложил, чтобы добавить 0 к переменной. В моем случае лучшее место было перед циклом, так как образцы были переписаны во время действия AWK-скрипта. Благодарю.

+0

Возможно ли, что переменная 'sample' содержит возврат каретки? Это может произойти, если входной файл был создан в Windows, а $ 24 - последнее поле в строке. Конечно, в этом случае длина (образец) будет равна 5 вместо 4, поэтому вы должны были заметить, что именно так вы показываете длину. – rici

+0

или отредактируйте свой вопрос, чтобы включить самый маленький набор данных, который воспроизводит проблему (не 8092 строки!) И ваш ожидаемый результат с этого ввода. Удачи. – shellter

ответ

1

awk определяет тип переменной в зависимости от того, какое значение хранится в переменной. Вы можете заставить его набирать то, что вы хотите, хотя это немного хаки (это еще не все).

Попробуйте добавить 0 к переменной перед тем, как нажать на цикл for. $sample = $sample + 0, например. Теперь, независимо от того, что awk подумал, прежде чем вы нажмете эту строку, теперь он будет обрабатывать ваш номер как число, и ваш цикл for должен выполняться так, как ожидалось.

Нечетный, хотя он выполнялся вообще и останавливался на 9 итерациях .... Он предполагает, что, возможно, он уже правильно относится к нему, и вы можете предположить, что значение равно 8092, когда оно есть, фактически 9. Кроме того, этот печатный бит внутри цикла for никогда не должен выполняться. Надеюсь, это не выводит.

2

Awk не точно «конвертирует» между представлениями, он просто использует все, что вы ему даете, настраивая контекст на основе использования. Таким образом, при оценке булевых значений любое ненулевое число оценивается как TRUE, а любая строка, кроме "0", имеет значение TRUE.

я не могу увидеть, что действительно в вашей samples переменной, но если вы хотите, чтобы заставить вещи должны быть оценены как число, прежде чем начать свой цикл, вы можете быть в состоянии просто добавить ноль в переменной Ie:

samples = $24 + 0; 

Кроме того, если ваши исходные данные пришли из машины DOS/Windows и имеют окончания строк, которые включают в себя возврат каретки (\r\n), и $24 последнего поле в каждой строке, то вы можете быть сравнение i против 24\r , что, скорее всего, не даст вам ожидаемых результатов.

Чтобы увидеть, что действительно в ваших входных данных, попробуйте:

cat -vet samples | less 

Если вы видите ^M до $ в конце каждой строки, то ваш входной файл содержит возврат каретки, и вы должны обработать это необходимо, прежде чем просить awk проанализировать его содержимое.

На самом деле, я думаю, что это довольно ясно, что, так как ваш ввод данных начинается с символа «8» и ваш цикл останавливается на 9-й итерации, ваше сравнение i к samples является одним из строк, а не чисел.

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