我有两个执行 awk 脚本的 bash 脚本。它应该过滤掉被阻止的用户:
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}"
您可以看到,从字面上看,唯一的区别是花括号
{
在正则表达式匹配短语末尾的位置。
现在,当我针对测试数据运行此脚本时 (
user=evil_user;file=data.csv; . testawk.sh
),我得到了不同的结果。
数据.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.
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
我不明白为什么?
注意:在脚本中间接调用 bash 是为了允许
${file}
进行文件路径通配扩展。
是的。在 awk 条件/操作对中,操作必须与条件在同一行开始。 Awk 不是一种自由格式的语言。
所以当你这样做时:
/whatever/
{ something }
最终会打印与 /whatever/ 匹配的每一行,并对每一行执行 { some } 。如果存在重叠,您会得到重复的内容。