Если command
может взять весь список значений один раз и сгенерировать преобразованный список в качестве вывода (например, tr 'a-z' 'A-Z'
), тогда вы захотите сделать что-то подобное, чтобы избежать порождения оболочки один раз для каждой строки ввода (чтоочень медленно):
awk -F' *[|] *' '{print $2}' file |
command |
awk -F' *[|] *' -v OFS=' | ' 'NR==FNR{a[FNR]=$0; next} {$2=a[FNR]} 1' - file
в противном случае, если command
требуется для вызова с одним значением за раз (например, echo
), или вы просто не заботитесь о скорости выполнениятогда вы сделаете:
awk -F' *[|] *' -v OFS=' | ' '{
cmd = "command \047" $2 "\047"
if ( (cmd | getline line) > 0 ) {
$2 = line
}
close(cmd)
print
}' file
\047
s выдаст одинарные кавычки вокруг $2
при передаче на command
и защитит его от интерпретации оболочки (см. https://mywiki.wooledge.org/Quotes)и проверка результата getline защитит вас от перезаписи текущих $ 2 без вывода на экран вывода более раннего выполнения команды в случае сбоя (см. http://awk.freeshell.org/AllAboutGetline). close()
гарантирует, что вы не завершите работуошибка «слишком много открытых файлов» или другая загадочная проблема, если канал не закрывается должным образом, например, если команда генерирует несколько строк, а вы просто читаете первую.
Учитывая ваш комментарийниже, если вы идете со вторым подходом выше, то вы напишите что-то вроде:
awk -F' *[|] *' -v OFS=' | ' '{
cmd = "openstack show \047" $2 "\047"
while ( (cmd | getline line) > 0 ) {
split(line,flds)
if ( flds[2] == "name" ) {
$2 = flds[3]
break
}
}
close(cmd)
print
}' file