OSX, G/AWK, Bash — недопустимый оператор, незавершенная строка и отсутствие вывода файла

У меня есть сценарий, который кто-то из SO любезно предоставил для решения проблемы, с которой я столкнулся. Однако у меня возникли некоторые проблемы с его работой на OSX.

gawk --version
GNU Awk 3.1.6

awk --version
awk version 20100208

Первоисточник:

awk -F, -vOFS=, -vc=1 '
NR == 1 {
    for (i=1; i<NF; i++) {
        if ($i != "") {
            g[c]=i;
            f[c++]=$i
        }
    }
}
NR>2 {
    for (i=1; i < c; i++) {
        print $1,$2, $g[i] > "output_"f[i]".csv
    }
}' data.csv

Когда я запускаю скрипт, он выдает следующую ошибку:

awk: syntax error at source line 12
context is print $1,$2, $g[i] > >>>  "output_"f <<< [i]".csv
awk: illegal statement at source line 13

Судя по всему, переменная [i] не была изменена в выходном файле, но я не знаю почему.

Если я изменю AWK на GAWK и запущу исходный скрипт, вот результат:

gawk: cmd. line:11:             print $1,$2, $g[i] > "output_"f[i]".csv
gawk: cmd. line:11:                                               ^ unterminated string

Поэтому я редактирую соответствующую строку, чтобы исправить незавершенную строку

print $1,$2, $g[i] > "output_"f[i]".csv"

Потом проходит нормально, ошибок не выдает, но выходных файлов нет.

Любые идеи? Я провел большую часть прошлой ночи и сегодняшнего утра, изучая это.

Пример входного файла:

,,L1,,,L2,,,L3,,,L4,,,L5,,,L6,,,L7,,,L8,,,L9,,,L10,,,L11,
Title,r/t,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,neede d,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst,needed,actual,Inst
EXAMPLEfoo,60,6,6,6,0,0,0,0,0,0,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
EXAMPLEbar,30,6,6,12,6,7,14,6,6,12,6,6,12,6,8,16,6,7,14,6,7.5,15,6,6,12,6,8,16,6,0,0,6,7,14
EXAMPLE1,60,3,3,3,3,5,5,3,4,4,3,3,3,3,6,6,3,4,4,3,3,3,3,4,4,3,8,8,3,0,0,3,4,4
EXAMPLE2,120,6,6,3,0,0,0,6,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
EXAMPLE3,60,6,6,6,6,8,8,6,6,6,6,6,6,0,0,0,0,0,0,6,8,8,6,6,6,0,0,0,0,0,0,0,10,10
EXAMPLE4,30,6,6,12,6,7,14,6,6,12,6,6,12,3,5.5,11,6,7.5,15,6,6,12,6,0,0,6,9,18,6,0,0,6,6.5,13

И выходной пример должен быть

Таким образом, для L1 пример вывода будет выглядеть так:

EXAMPLEfoo,60,6
EXAMPLEbar,30,6
EXAMPLE1,60,3
EXAMPLE2,120,6
EXAMPLE3,60,6
EXAMPLE4,30,6

И для L2:

EXAMPLEfoo,60,0
EXAMPLEbar,30,6
EXAMPLE1,60,3
EXAMPLE2,120,0
EXAMPLE3,60,6
EXAMPLE4,30,6

person S1syphus    schedule 13.04.2010    source источник
comment
Если вы удалите перенаправление и имя файла, вы получите вывод на стандартный вывод?   -  person Dennis Williamson    schedule 13.04.2010
comment
Ой! Эта отсутствующая закрывающая цитата была моей опечаткой в ​​мой ответ. Я исправлю это.   -  person Dennis Williamson    schedule 13.04.2010
comment
Вынул и перенаправление, и имя файла, ничего странного. Также поместите файл .csv через dos2unix, чтобы удалить любые мелкие проблемы с новой строкой и концом файла, но все равно без вывода. Что, честно говоря, я нахожу очень странным.   -  person S1syphus    schedule 14.04.2010
comment
Почти уверен, что это специфичная для OSX проблема, только что установил Gentoo на работе, чтобы протестировать скрипт, работает отлично.   -  person S1syphus    schedule 14.04.2010
comment
На всякий случай попробуйте установить все переменные инициализации в предложении BEGIN, а не в командной строке. И поместите оператор print "here 1" (или 2) над каждым циклом for для целей отладки. И попробуйте ghostdog74 версия   -  person Dennis Williamson    schedule 14.04.2010
comment
Исправлено, новые ошибки строки меня напортачили   -  person S1syphus    schedule 15.04.2010


Ответы (1)


Я вижу две проблемы (на платформе OS X):

  1. Команда awk в OS X не поддерживает флаг -v. Мы можем исправить это, используя шаблон BEGIN.
  2. OS X awk не нравится способ построения выходного файла в строке печати.

Вот мое решение, которое работает как на Mac OS X Snow Leopard, так и на Red Hat Linux 4.x:

awk -F, '
BEGIN { OFS=","; c=1 } # FIX problem 1
NR == 1 {
    for (i=1; i<NF; i++) {
        if ($i != "") {
            g[c]=i;
            f[c++]=$i
        }
    }
}
NR>2 {
    for (i=1; i < c; i++) {
        outfile=sprintf("output_%s.csv", f[i]) # FIX problem 2
        print $1,$2, $g[i] > outfile
    }
}' data.csv
person Hai Vu    schedule 14.04.2010
comment
Согласно справочной странице Apple для AWK, опция -v поддерживается. И OP удалил перенаправление и все еще не получил никакого вывода. Происходит что-то другое. - person Dennis Williamson; 15.04.2010
comment
Деннис: Да, на справочной странице (по крайней мере, для Snow Leopard) указано, что -v поддерживается, но я попробовал простую команду awk -vmyvar=5 '{BEGIN print myvar}', и она не работает, жалуясь на awk: недопустимо -v вариант - person Hai Vu; 15.04.2010
comment
Я предполагаю, что это просто опечатка, но BEGIN стоит вне фигурных скобок. Попробуйте поставить пробел между -v и myvar, чтобы увидеть, имеет ли это значение. - person Dennis Williamson; 15.04.2010
comment
Денис: Это была опечатка. Вставка пробела работает: awk -v myvar=5 'BEGIN{print myvar}'. Спасибо. - person Hai Vu; 16.04.2010