如何实现grep优先匹配行尾模式,无匹配时再匹配任意位置?
解决方案
使用awk可以一次遍历完成判断,无需重复处理输入,完美实现需求:
标准单行命令
matches="$(<run command> | awk -v input="$input_str" ' $0 ~ input "$" { end_hits[++n] = $0 } $0 ~ input { contains_hits[++m] = $0 } END { if (n > 0) { for (i=1; i<=n; i++) print end_hits[i] } else { for (i=1; i<=m; i++) print contains_hits[i] } } ')"
紧凑简化版
如果需要更简洁的写法:
matches="$(<run command> | awk -v s="$input_str" '$0~s"$"{a[++x]=$0} $0~s{b[++y]=$0} END{for(i=1;i<=(x?x:y);i++)print x?a[i]:b[i]}')"
命令解释
-v input="$input_str":将脚本的输入参数传递给awk的变量input;- 第一个规则
$0 ~ input "$":匹配以输入字符串结尾的行,存入数组end_hits; - 第二个规则
$0 ~ input:匹配所有包含输入字符串的行,存入数组contains_hits; END块:判断end_hits是否有内容,有则输出这些行,否则输出contains_hits的内容。
测试验证
针对command.out文件,用以下命令测试:
输入
B:cat command.out | awk -v s="B" '$0~s"$"{a[++x]=$0} $0~s{b[++y]=$0} END{for(i=1;i<=(x?x:y);i++)print x?a[i]:b[i]}'输出:
B输入
C:cat command.out | awk -v s="C" '$0~s"$"{a[++x]=$0} $0~s{b[++y]=$0} END{for(i=1;i<=(x?x:y);i++)print x?a[i]:b[i]}'输出:
C1 C2 C3输入
Z:cat command.out | awk -v s="Z" '$0~s"$"{a[++x]=$0} $0~s{b[++y]=$0} END{for(i=1;i<=(x?x:y);i++)print x?a[i]:b[i]}'输出:
XYZ输入
Y:cat command.out | awk -v s="Y" '$0~s"$"{a[++x]=$0} $0~s{b[++y]=$0} END{for(i=1;i<=(x?x:y);i++)print x?a[i]:b[i]}'输出:
XYZ XYZ1 XYZ2
内容的提问来源于stack exchange,提问作者Shane
相关产品推荐
相关产品推荐

