如何在Bash脚本中用含点的变量精准匹配文件列内容?
解决精确匹配含特殊字符的列提取问题
我来帮你搞定这个问题!先理清楚你遇到的状况:
你有一个三列的文件myFile.txt,内容是:
amy. A B amy5 B A amy.smit F P smit_rees C D
你想提取第一列正好等于变量var值的行的第二列,当你执行var='amy.'后用grep "$var" myFile.txt | awk '{ print $2 }',结果却得到了A B F,而你只想要A。
问题出在哪?
grep默认是正则表达式匹配,而.在正则里是特殊字符,代表「任意单个字符」。所以amy.会匹配所有以amy开头、后面跟任意一个字符的行:
amy.:.匹配自身amy5:.匹配数字5amy.smit:.匹配字母s
这三行都被grep捞出来了,自然第二列的结果就不对了。
两个靠谱的解决方案
方案1:用awk直接完成(更高效,推荐)
不用分开调用grep和awk,直接让awk做精确匹配,还能避免转义的麻烦:
var='amy.' awk -v user="$var" '$1 == user {print $2}' myFile.txt
-v user="$var":把shell里的var变量传递给awk的user变量$1 == user:精确判断第一列是否和user完全相等- 符合条件的行就打印第二列,结果正好是
A。
方案2:用grep做固定字符串+整列匹配
如果你一定要用grep,需要两个关键设置:
- 用
-F参数让grep把字符串当成固定文本(不解析正则特殊字符) - 加上行首
^和第一列后的空格,确保只匹配第一列完全等于var的行:
var='amy.' grep -F "^$var " myFile.txt | awk '{print $2}'
-F:关闭正则解析,.就只是普通的点号^$var:^表示行的开头,后面跟你的变量值,再跟一个空格——这样就保证只匹配第一列正好是amy.的行(因为第一列和第二列是空格分隔),不会误匹配amy.smit这类行。
这样执行后就能得到你想要的A啦!
内容的提问来源于stack exchange,提问作者Morticia A. Addams
相关产品推荐
相关产品推荐

