Подтвердить что ты не робот

Как передать переменные из awk в команду оболочки?

Я пытаюсь запустить команду оболочки из awk для каждой строки файла, а команде оболочки требуется один входной аргумент. Я попытался использовать system(), но он не распознал входной аргумент.

Каждая строка этого файла является адресом файла, и я хочу запустить команду для обработки этого файла. Итак, для простого примера я хочу использовать команду "wc" для каждой строки и передать $1 в wc.

awk '{system("wc $1")}' myfile
4b9b3361

Ответ 1

вы близки. вам нужно объединить командную строку с переменными awk:

awk '{system("wc "$1)}' myfile

Ответ 2

Вы не можете захватить вывод вызова awk system(), вы можете получить только статус выхода. Используйте getline/pipe или конструкцию getline/variable/pipe

awk '{
    cmd = "your_command " $1
    while (cmd | getline line) {
        do_something_with(line) 
    }
    close(cmd)
}' file

Ответ 3

FYI здесь, как использовать awk для обработки файлов, имена которых хранятся в файле (предоставляя wc-подобные функции в этом примере):

gawk '
NR==FNR { ARGV[ARGC++]=$0; next }
{ nW+=NF; nC+=(length($0) + 1) }
ENDFILE { print FILENAME, FNR, nW, nC; nW=nC=0 }
' file

В приведенном выше примере используется GNU awk для ENDFILE. С другими awks просто сохраняйте значения в массиве и печатайте в цикле в разделе END.

Ответ 4

Или используйте трубу |, как в bash, затем извлеките вывод в переменной с awk getline, как этот

 zcat /var/log/fail2ban.log* | gawk  '/.*Ban.*/  {print $7};' | sort | uniq -c | sort | gawk '{ "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip}'

Эта строка будет печатать все заблокированные IP-адреса с вашего сервера вместе с их происхождением (страной) с помощью пакета geoip-bin.

Последняя часть этого однострочного слоя относится к нам:

gawk '{ "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip}'

Он просто говорит: запустите команду "geoiplookup 182.193.192.4 | -f2 -d:" ($ 2 заменяется, как вы можете догадаться) и поместите результат этой команды в geoip (бит | getline geoip). Затем напечатайте что-нибудь и что-нибудь внутри переменной geoip.

Полный пример и результаты можно найти здесь, статью, которую я написал.