Intereting Posts
Как использовать расширенные атрибуты для предварительного просмотра изображения? i3wm проверить, существует ли контейнер в рабочей области Не удается заставить USB-адаптер ethernet работать под CentOS 6 минимальным Выполнение команд в процессе повышенного bash путем записи на стандартный ввод его родительского скриптового процесса Linux HID-драйвер для беспроводных клавиатур Primax Нужно ли шифровать файл swap *, если он будет находиться в зашифрованном корневом файле? Изменить права доступа к папке FTP через SSL в AIX (UNIX) Ubuntu 15.10 Название сетевых интерфейсов Открыть интерактивный текст в emacs в новом / соседнем окне Что такое альтернатива zcache? tar конкретных файлов на основе шаблона Virtual Box – проблема с общими папками в Ubuntu 16.04 CUPS: добавление сбой принтера с помощью «Не удалось получить список драйверов принтера:« Успех » Как установить os-prober в debian / bunsenlabs?

Передача аргументов в скрипт awk

У меня есть сценарий awk, где я хочу иметь возможность передавать N аргументов в него, а также читать из стандартного ввода Я хотел бы иметь возможность сделать что-то вроде

tail -f logfile | my_cool_awk_scipt var1 var2 var3 ... varN

А затем используйте эти переменные внутри скрипта.

 #!/bin/awk -f BEGIN { print "AWK Script Starting" print ARGV[1] } { if ($0 < ARGV[1]) print $0 else if ($0 < ARGV[2]) print $0 + ARGV[2] } 

Если я пытаюсь передать переменные как есть, выведите ARGV[1] а затем нажмите

 awk: ./my_cool_awk_script:4: fatal: cannot open file `var1' for reading (No such file or directory) 

Я могу сделать,

 tail -f logfile | my_cool_awk_scipt -v var1=var1 -v var2=var2 -v var3=var3 ... varN=varN 

но это немного ограниченно и многословно. Я знаю, что могу также обернуть это в сценарий оболочки, но я не уверен, как правильно встроить то, что у меня есть, в нечто подобное

Заранее спасибо.

В тот момент, когда awk попадает в основную часть скрипта, после BEGIN он захочет прочитать имена файлов, указанные в ARGV [x]. Так что просто взорвите их.

 $ cat a.awk #!/bin/awk -f BEGIN { print "AWK Script Starting" ZARGV[1]=ARGV[1] ZARGV[2]=ARGV[2] ARGV[1]="" ARGV[2]="" } { if ($0 < ZARGV[1]) print $0 else if ($0 < ZARGV[2]) print $0 + ZARGV[2] } $ 

Пример:

 $ cat logfile 1 2 3 4 5 $ ./a.awk 3 4  

Просто для удовольствия (и это, безусловно, НЕ рекомендуемый способ сделать это): поскольку awk не знает о «позиционных параметрах» (PP), а только присваивает переменные и имена входных файлов, нам нужно разобрать PP и отличить их от двух других. Это можно сделать, либо разделив PP с фиксированным токеном, например -- (который также используется в другом контексте), либо узнав количество PP, фиксированное или переданное, например, в ARGV [1]). Пытаться

  awk ' BEGIN {while (ARGV[++MXPP] != "--") PP[MXPP] = ARGV[MXPP] for (j=MXPP+1; j 

Если вы используете stdin вместо входных файлов, передавая sth внутрь, вы можете опустить токен и получить PP до конца списка (т.е. установить токен в "")

Вы уже знаете о -v variable=value . Другой способ – передать переменные через среду и прочитать их из массива ENVIRON :

 $ var1=hello var2=world awk 'BEGIN { print ENVIRON["var1"], ENVIRON["var2"] }' hello world 

Это устанавливает переменные окружения var1 и var2 в окружении awk .

Или же,

 $ export var1=hello var2=world $ awk 'BEGIN { print ENVIRON["var1"], ENVIRON["var2"] }' hello world 

Это устанавливает переменные в вызывающей среде перед вызовом awk .

Массив ARGV содержит только имена файлов, из которых программа awk будет последовательно читать, но он также может содержать имена переменных, заданные в командной строке, как в

 awk '...' var1=value1 var2=value2 filename 

Обычно это не рекомендуемый способ передачи переменных в awk (например, эти переменные не будут доступны в блоке BEGIN ).

Вы можете создать скрипт, как это:

 #!/bin/bash vars=() i=1 for arg in "$@"; do vars+=(-v "var$i=$arg") i=$((i+1)) done awk "${vars[@]}" -f/dev/fd/3 3<< EOF BEGIN { printf "awk var1: %s\n", var1; printf "awk var2: %s\n", var2; } 1 EOF 

и затем запустите его:

 $ echo some input | ./awk.sh foo bar doo awk var1: foo awk var2: bar some input 

Сценарий оболочки создаст командную строку из этих аргументов -v var1=... и передаст их в awk вместе с реальной программой awk через here-doc (конечно, вместо этого вы можете поместить скрипт awk в отдельный файл ). Вы не можете передавать никакие имена входных файлов таким образом, однако вы вынуждены читать скрипт awk из stdin.

По крайней мере, GNU awk явно документирует, что ARGV[n] также используется в качестве входных файлов ( https://www.gnu.org/software/gawk/manual/html_node/ARGC-and-ARGV.html ), поэтому вы получить ошибки "файл не найден".