Как сжать полученный результат команды awk?

Я попробовал это, но это не сработало. Как я могу сгенерировать вывод в виде файла gz из команды awk?

 awk -v someVariable="$VAR1" '
        BEGIN {
         . . .
        }

        {
           SOME CODES HERE
        }
        END {}
    ' $FILES> gzip $RESULTING_OUTPUT

3 ответа

Вы можете ЛИБО направить свой вывод в gzip вне awk (как предложил Том), или вы можете отправить вывод через каналы изнутри awk. Как это:

awk '
  {
    print | "gzip > /path/to/output.gz";
  }
' inputfile

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

awk '

  # given:
  #   Mar 20 13:29:12 servername some message

  BEGIN {
    m["jan"]="01"; m["feb"]="02"; m["mar"]="03"; m["apr"]="04"; 
    m["may"]="05"; m["jun"]="06"; m["jul"]="07"; m["aug"]="08"; 
    m["sep"]="09"; m["oct"]="10"; m["nov"]="11"; m["dec"]="12";
  }

  {
    output=sprintf("gzip -9 > /var/log/split/%s-%s-%s.log.gz", m[tolower($1)], $2, substr($3,1,2));
    print | output
  }' input.log

При таком использовании ваша выходная командная строка gzip переоценивается для каждой строки ввода, и awk не закрывает канал, пока не получит указание вручную или в awk не хватит ввода и выхода.

Мой собственный вариант использования для этого заключался в том, что мы собирали журналы веб-сервера из CDN, которые были не в хронологическом порядке. Журналы были слишком большими для sort, но может обрабатываться при разбивке на почасовые куски.

YMMV. Лучшее решение зависит от того, чего вы на самом деле пытаетесь достичь, чего вы нам не сказали.

Вы должны передать вывод gzip, затем перенаправить, а затем вывести в файл:

awk '...' $FILES | gzip > "$RESULTING_OUTPUT"

Обратите внимание, что заглавные буквы для имен переменных не рекомендуются, так как они могут конфликтовать с внутренними переменными оболочки. Также, $FILES выглядит подозрительно, как будто он может содержать список из более чем одного имени файла. Вы действительно должны использовать массив, который вы можете передать как "${files[@]}"

Это сработало

 awk -v someVariable="$VAR1" '
            BEGIN {
             . . .
            }

            {
               SOME CODES HERE
            }
            END {}
        ' $FILES> $RESULTING_OUTPUT
    gzip $RESULTING_OUTPUT
Другие вопросы по тегам