Ответ 1
Выяснено.
Мы используем awk Двунаправленный ввод-вывод
{
"strip $1" |& getline $1
}
передает $1 для полосы, и getline выводит из полосы обратно в $1
Я хочу запустить команду system
в awk script и получить ее вывод, хранящийся в переменной. Я пытался это сделать, но вывод команды всегда идет в оболочку, и я не могу ее захватить. Любые идеи о том, как это можно сделать?
Пример:
$ date | awk --field-separator=! {$1 = system("strip $1"); /*more processing*/}
Должна вызывать системную команду strip
и вместо отправки вывода в оболочку, для возврата к возврату на $1
для дальнейшей обработки. Rignt теперь отправляет вывод в оболочку и присваивает команду retcode $1
.
Выяснено.
Мы используем awk Двунаправленный ввод-вывод
{
"strip $1" |& getline $1
}
передает $1 для полосы, и getline выводит из полосы обратно в $1
Примечание: Копроцесс специфичен для GNU awk. В любом случае, другой альтернативой является использование getline
cmd = "strip "$1
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd)
Вызов close(cmd)
не позволит awk
выдать эту ошибку после нескольких вызовов:
Неустранимый: невозможно открыть канал '…' (Слишком много открытых файлов)
Чтобы запустить системную команду в awk
вы можете использовать system()
или cmd | getline
cmd | getline
.
Я предпочитаю cmd | getline
cmd | getline
потому что он позволяет вам поймать значение в переменной:
$ awk 'BEGIN {"date" | getline mydate; close("date"); print "returns", mydate}'
returns Thu Jul 28 10:16:55 CEST 2016
В более общем плане вы можете установить команду в переменную:
awk 'BEGIN {
cmd = "date -j -f %s"
cmd | getline mydate
close(cmd)
}'
Обратите внимание, что важно использовать функцию close()
чтобы предотвратить ошибку "делает слишком много открытых файлов", если у вас есть несколько результатов (спасибо mateuscb за то, что указали это в комментариях).
Используя system()
, вывод команды печатается автоматически, и значение, которое вы можете уловить, - это код возврата:
$ awk 'BEGIN {d=system("date"); print "returns", d}'
Thu Jul 28 10:16:12 CEST 2016
returns 0
$ awk 'BEGIN {d=system("ls -l asdfasdfasd"); print "returns", d}'
ls: cannot access asdfasdfasd: No such file or directory
returns 2
gawk '{dt=substr($4,2,11); gsub(/\//," ",dt); "date -d \""dt"\" +%s"|getline ts; print ts}'
Вы можете использовать это, когда вам нужно обработать вывод grep:
echo "some/path/exex.c:some text" | awk -F: '{ "basename "$1"" |& getline $1; print $1 " ==> " $2}'
опция -F:
указать awk для использования :
качестве разделителя полей
"basename "$1""
выполнить команду basename
оболочки в первом поле
|& getline $1
читает вывод предыдущей команды оболочки в подпотоке
output:
exex.c ==> some text