如何避免awk的‘字符串中存在换行符’错误及传递含换行符参数
关于awk处理带换行符字符串的两个问题解答
咱们先来看你给出的报错场景:
awk -v s='text' 'BEGIN { print(s) }' text awk -v s=$'\n''text' 'BEGIN { print(s) }' awk: newline in string text... at source line 1
这个错误是因为用-v选项传递带换行符的变量时,shell会把换行符直接暴露给awk的语法解析器,awk会把换行符当成语句的结束,从而触发语法错误。下面分别解决你的两个问题:
1. 如何避免awk中的“字符串中存在换行符”错误?
核心思路是不让awk在解析变量赋值语句时直接接触到换行符,可以用以下几种实用方法:
通过环境变量传递
先在shell中导出环境变量,再在awk里通过ENVIRON数组读取,这种方式完全绕开了awk对变量赋值语句的语法解析:export MY_STR=$'\ntext' awk 'BEGIN { print(ENVIRON["MY_STR"]) }'用命令替换生成字符串
借助printf生成带换行的字符串,通过命令替换传递给-v选项,shell会帮我们处理好换行符的传递逻辑:awk -v s="$(printf '\ntext')" 'BEGIN { print(s) }'使用here-doc传递变量
这种方式也能避免awk直接解析带换行的赋值语句:awk 'BEGIN { print(s) }' s="$'\ntext'" <<EOF EOF
2. 如何将包含换行符的命令行参数传递给awk?
可以通过以下几种可靠的方式传递带换行的参数:
利用awk的ARGV数组
命令行中除了awk脚本和选项外的参数,都会被存入ARGV数组,直接读取数组元素即可:awk 'BEGIN { print(ARGV[1]) }' $'\ntext'继续使用环境变量传递
这其实也是一种参数传递的思路,而且不受命令行解析规则的限制,稳定性很高,用法和第一个问题里的环境变量方法一致。用引号包裹带换行的参数
在bash等支持$''语法的shell中,用双引号把带换行的字符串包裹起来,传递给awk的变量:awk 'BEGIN { print(s) }' s="$'\ntext'"
内容的提问来源于stack exchange,提问作者exbuddha
相关产品推荐
相关产品推荐

