AWK动态获取外部命令输出赋值变量及变量拼接实现方法
AWK 动态赋值与变量拼接问题解答
静态字符串拼接基础
AWK原生支持无操作符直接拼接字符串,静态赋值写法简洁:
% awk 'BEGIN { str1 = "foo"; str2 = "bar"; str3 = str1 str2; print str3 }' foobar
该写法仅支持硬编码固定值,无法动态获取外部命令执行结果。
动态获取外部命令输出赋值
AWK语法中$为字段引用符,不具备Shell的命令替换语义,直接在代码块内写$(echo "foo")会被识别为字段引用,触发语法错误:
% awk 'BEGIN { str1 = $(echo "foo"); str2 = "bar"; str3 = str1 str2; print str3 }' awk: illegal field $(foo), name "(null)" source line number 1
纯AWK原生支持通过管道读取外部命令输出,无需依赖Shell层提前做值替换,实现方式为通过getline读取管道输入到变量:
awk 'BEGIN { cmd = "echo \"foo\"" cmd | getline str1 close(cmd) str2 = "bar" print str1 str2 }'
执行后正常输出foobar。
注意:通过
getline读取管道输出后,必须调用close()关闭对应命令的管道句柄,避免文件句柄泄漏;多次调用同一命令未关闭句柄时,会出现无法读取新输出的异常。
通过-v参数传入外部命令输出是Shell层先完成命令替换、再传值给AWK的方案,不属于AWK内部实现:
% awk -v str1="$(echo "foo")" 'BEGIN {str2 = "bar"; print str1 str2 }' foobar
跨变量引用赋值实现
多-v传参时无法引用前一个变量值的本质原因:所有-v参数的赋值动作均在Shell层独立执行,Shell处理第二个-v的命令替换逻辑时,AWK进程尚未启动,无法识别AWK语境下才会定义的变量,因此最终只会输出字面量str1bar:
% awk -v str1="$(echo "foo")" -v str2="$(echo str1)bar" 'BEGIN {print str2 }' str1bar
纯AWK层面不存在跨层变量作用域问题,只需在AWK代码块内按顺序赋值,即可直接引用已定义的变量完成拼接、计算,无需在Shell层提前定义中间变量:
awk 'BEGIN { # 完成第一个变量赋值 cmd = "echo \"foo\"" cmd | getline str1 close(cmd) # 直接引用已赋值的str1拼接生成第二个变量 str2 = str1 "bar" # 基于str2执行后续逻辑 print str2 }'
执行后输出预期结果foobar。如果仅涉及AWK内部变量的传递拼接,无需调用外部命令时,直接按顺序书写赋值语句即可,无额外语法限制。
内容的提问来源于stack exchange,提问作者joseluisbz
相关产品推荐
相关产品推荐

