почему этот сценарий awk ведет себя не так, как ожидается? - PullRequest
1 голос
/ 29 июня 2011

У меня есть следующий тестовый скрипт

 /^[^a-zA-Z0-9]/  {
    DATEd[$3] = $1
    } 
   END { 
        print "        \"data\": ["
        for (i = 0 ; i <= 5; i ++ ) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

И читаем из этого текстового файла

2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399 
2011-01-22 22:12 P16A22_110114072915 22 1312 75 13.55 1399

Но он не распечатывает, что я хочу, я хочу, чтобы он распечатал

    "data": [
        [0, "2011-01-22"],
        [1, "2011-01-22"],
        [2, "2011-01-22"],
        [3, "2011-01-22"],
        [4, "2011-01-22"],
        [5, "2011-01-22"],
    ]

Когда это на самом деле только распечатки

"data": [
    [0, ""],
    [1, ""],
    [2, ""],
    [3, ""],
    [4, ""],
    [5, ""],
]

Так почему же "DATEd [$ 3] = $ 1" пусто?

Кроме того, как я могу проверить длину массива? DATEd.length в этом случае не работает.

Спасибо

EDIT_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___

Так что с помощью @Fredrik и @geekosaur я пришел куда-то с этим, теперь к некоторым последним вопросам

1) Сценарий теперь выглядит так

 /[a-zA-Z0-9]/  {
    DATEd[NR-1] = $1
    } 
   END { 
        print "        \"data\": ["

        for (i in DATEd) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

И дает следующий вывод

"data": [
    [4, "2011-01-26"],
    [5, "2011-01-27"],
    [6, "2011-01-28"],
    [0, "2011-01-22"],
    [1, "2011-01-23"],
    [2, "2011-01-24"],
    [3, "2011-01-25"],
]

Но я хочу, чтобы это выглядело так

"data": [
[0, "2011-01-22"],
[1, "2011-01-23"],
[2, "2011-01-24"],
[3, "2011-01-25"],
[4, "2011-01-26"],
[5, "2011-01-27"],
[6, "2011-01-28"]
]

I.E. Сортировать и удалить последний символ ',' перед последним закрывающим символом ']'. Можно ли это легко получить? =)

Спасибо =)

РЕДАКТИРОВАТЬ 3 Окончательный результат_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ____

Использовал комбинацию @geekosaur и @Fredrik contrib's =)

{
    DATEd[NR-1] = $1; len++
}
   END { 
        print "        \"data\": ["

        #for (i in DATEd) {
        for (i = 0 ; i <= len-1; i ++ ) {
            { print "            [" i ", \"" DATEd[i] "\"],"}
        }
        print "        ]"
}

Ответы [ 2 ]

0 голосов
/ 29 июня 2011

При отсутствии опции -F, $3 будет P16A22_110114072915 (или было бы, если бы регулярное выражение вашего селектора было правильным). Какую ценность вы на самом деле хотите там? Возможно, вы хотите NR?

awk не является объектно-ориентированным; и его поддержка массивов, чтобы быть добрым, отсутствует. Вам нужно будет самостоятельно отслеживать длину массива. (Просто чтобы дать вам представление о том, насколько ограничена поддержка массива awk: вы не можете назначить массив. Вы должны назначить отдельные индексы или использовать split().)

0 голосов
/ 29 июня 2011

В качестве начала, ваше регулярное выражение неверно, /^[^a-zA-Z0-9]/ означает совпадение с началом строки, а НЕ после буквы или цифры.Ни одна из строк не имеет такой настройки, следовательно, ваш массив DATe пуст.

Во-вторых, ваш массив не индексируется 0-5, а вместо содержимого 3 $ (если вы исправите свое регулярное выражение)

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

Пример массива

function array_length(a) {
    for (i in a) n++
    return n
}

{
    DATEd[NR] = $1
}
END {
    for (i in DATEd) {
        print i, DATEd[i]
    }
    print "Number of items", array_length(DATEd)

    # copy indices
    j = 1
    for (i in DATEd) {
        ind[j] = i    # index value becomes element value
        j++
    }
    n = asort(ind)    # index values are now sorted
    for (i = 1; i <= n; i++)
        print i, DATEd[ind[i]]
}

Дает:

4 2011-01-22
5 2011-01-22
6 2011-01-22
1 2011-01-22
2 2011-01-22
3 2011-01-22
Number of items 6
1 2011-01-22
2 2011-01-22
3 2011-01-22
4 2011-01-22
5 2011-01-22
6 2011-01-22

См. Руководство gnu awk для описания массивов.

Слишком циклически перебирайте все элементы массива, используйте эту конструкцию (см. Ссылку выше)

 for (var in array)
   body
...