我有一个这样的文本文件:
tets v1.0
psutil==4.1.0
tclclean==2.4.3
test v2.0
psutil==3.1.1
pyYAML==3.11
not_test
psutil==4.1.0
tclclean==2.8.0
我正在使用awk和用户的输入来查找特定块第一行下的文本。我使用的命令是(其中user_in是用户的输入)...
awk -v ORS='nn' -v RS= -v FS='n' "$1 ~ "^$user_in$"" myfile.txt
问题是,如果用户输入".*",awk 语句将把它当作正则表达式并给我所有三个块,但我不希望输出任何东西,因为它与任何第一行都不匹配字面意思。
我想说的是,有没有办法在awk中禁用正则表达式并以字面方式获取每个字符(以与fgrep相同的方式)?
阅读 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。
现在让我们清理您的脚本:
awk -v ORS='nn' -v RS= -v FS='n' "$1 ~ "^$user_in$"" myfile.txt
不要将任何工具的任何脚本括在双引号中,始终使用单引号,这样您就不会陷入反斜杠逃逸的地狱。所以上面变成了:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" '$1 ~ "^"user_in"$"' myfile.txt
如果你想测试一个字符串,那么只需测试一个字符串,而不是正则表达式,例如,查找 $1 以目标字符串开头的记录:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" 'index($1,user_in)==1' myfile.txt
或包含目标字符串:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" 'index($1,user_in)>=1' myfile.txt
或以目标字符串结尾:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" 'index($1,user_in)==(length($1)-length(user_in))' myfile.txt
或者,如果您想找到 $1 是目标字符串的情况,而不仅仅是从它开始(就像您的脚本尝试的那样),那就更简单了:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" '$1 == user_in' myfile.txt
~
是正则表达式运算符。如果您不想使用正则表达式,请使用 ==
并且不要将您的输入包装在 ^...$
中,如下所示:
awk -v ORS='nn' -v RS= -v FS='n' "$1 == "$user_in"" myfile.txt
这仍然不够安全,因为例如,如果user_in
包含"
则该命令将不起作用。最好将其作为 awk 的user_in
变量传入:
awk -v ORS='nn' -v RS= -v FS='n' -v user_in="$user_in" '$1 == user_in'