如何使用grep等工具匹配文件中同一行同时包含多个指定字符串的行
问题描述
我有一个名为my.txt的文件,内容如下:
abc_default_flow #abc_default_flow -p sam abc_default_flow -p sam # abc_default_flow -p david abc_default_flow -p david -z what_is_it
我需要匹配符合以下所有条件的行:
- 非空行
- 不是以
#开头的注释行 - 同时包含所有指定的字符串
我一开始写的bash脚本有问题,匹配到部分字符串就跳出循环,没法命中同时包含所有字符串的行,调整后的嵌套if脚本可以实现需求,但代码太繁琐,请问有没有更简洁的grep、sed或awk单行命令可以替代多层嵌套if循环?
解决方案
1. awk单行(最推荐,可灵活扩展多关键词)
直接将变量传入awk进行匹配,不需要处理转义问题,逻辑清晰:
# 定义你的搜索关键词 f_name="abc_default_flow" p_name="david" # 匹配第一个符合条件的行并输出,和原脚本break逻辑一致 awk -v key1="$f_name" -v key2="$p_name" '!/^#/ && NF>0 && index($0,key1) && index($0,key2) {print $0; exit}' my.txt # 如果要实现原脚本中拼接输出f_name的逻辑,直接修改打印内容即可 awk -v key1="$f_name" -v key2="$p_name" '!/^#/ && NF>0 && index($0,key1) && index($0,key2) {print "f_name: " key1 "_" key2; exit}' my.txt
逻辑说明:
!/^#/:过滤所有以#开头的注释行NF>0:过滤空行index($0, 关键词):判断当前行包含对应字符串,比正则匹配更安全,不需要处理特殊字符的转义- 末尾
exit表示匹配到第一个符合条件的行就停止,不需要继续读文件,如果需要输出所有符合条件的行,删掉exit即可
2. grep组合实现
通过管道串联多个grep实现多条件匹配:
grep -v '^#' my.txt | grep -v '^$' | grep "$f_name" | grep "$p_name" | head -n1
逻辑说明:
grep -v '^#':删除注释行grep -v '^$':删除空行- 后续每个grep对应一个必须包含的关键词,有多少个关键词就加多少个grep
head -n1只取第一个匹配结果,要输出所有结果删掉即可
3. sed单行实现
sed -n '/^#/d; /^$/d; /'"$f_name"'/{/'"$p_name"'/{p;q}}' my.txt
逻辑说明:
/^#/d、/^$/d分别删除注释行和空行- 嵌套匹配两个关键词,匹配到就打印(
p)然后退出(q)
内容的提问来源于stack exchange,提问作者Vimo
相关产品推荐
相关产品推荐

