AWK中花括号{的位置是否会影响脚本执行结果?
AWK脚本花括号位置导致输出差异的原因
我写了两个调用AWK的Bash脚本,用于筛选被封禁的用户,二者唯一区别是AWK脚本里正则匹配表达式后花括号{的位置,但运行后输出结果完全不同。
两个脚本对比
testawk.sh
#!/usr/bin/bash awk_script_file=$(cat << 'EOF' $0 ~ "User " user ".* blocked" { print } EOF ) # Run awk through bash to get file globbing to work bash -c "awk -v user='${user}' '${awk_script_file}' ${file}"
testawk2.sh
#!/usr/bin/bash awk_script_file=$(cat << 'EOF' $0 ~ "User " user ".* blocked" { print } EOF ) # Run awk through bash to get file globbing to work bash -c "awk -v user='${user}' '${awk_script_file}' ${file}"
测试环境与结果
测试数据(data.csv)
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod User evil_user blocked: Limit exceeded ex ea commodo consequat. Duis aute irure dolor in reprehenderit User evil_user blocked: Limit exceeded Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
执行命令
user=evil_user;file=data.csv; . testawk.sh
输出结果
testawk.sh输出
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod User evil_user blocked: Limit exceeded User evil_user blocked: Limit exceeded ex ea commodo consequat. Duis aute irure dolor in reprehenderit User evil_user blocked: Limit exceeded User evil_user blocked: Limit exceeded Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
testawk2.sh输出
User evil_user blocked: Limit exceeded User evil_user blocked: Limit exceeded
差异原因解析
这是AWK的语法规则导致的:
testawk.sh中的AWK代码是两个独立的语句:
- 第一行
$0 ~ "User " user ".* blocked"是一个独立的匹配模式,没有指定动作,AWK会执行默认动作——打印当前匹配的行。 - 第二行的
{print}是一个没有匹配模式的动作块,意味着对每一行文本都会执行print操作。
最终效果:匹配正则的行会被打印两次(一次默认动作,一次无模式的print),不匹配的行被打印一次(无模式的print),所以输出里所有行都出现,且目标行重复。
- 第一行
testawk2.sh中的AWK代码是标准的「模式+动作」结构:
把匹配模式和动作块写在同一行,意味着只有当行匹配正则表达式时,才会执行print动作。所以最终只输出符合条件的两行。
说明:脚本中嵌套调用bash是为了实现
${file}的文件路径通配符展开。
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

