BASH:如果在同一行文本文件中找到两次模式,则匹配

时间:2013-09-26 14:35:35

标签: bash string-matching

如果我设法创建了一个充满这样的行的文件......

/VAULT14/620100_V14/620054 VOL1620054

如何让bash比较最后的2 * 6位数字,例如只有在行读取时才匹配

/VAULT14/620100_V14/620054 VOL1620541

基本上我所拥有的是tapelabs系统上虚拟磁带的路径列表,并且在同一行上,该磁带的实际VOL1磁带标头标签是什么。

我关心的是标签(VOL1)是否与实际的虚拟磁带文件名不匹配。

我确实尝试过使用awk,但必须遗漏一些内容:

echo "/VAULT14/620100_V14/620054 VOL1620054" | awk '{ if (substr($1,(length($1)-6)) == substr($2,(length($2)-6))) print "Same"; else print "Different" }'

当我认为它应该返回Different

时,返回Same

修改 感谢@shelter的评论,我意识到我实际上从长度上选了太多字符,因此/620054永远不会匹配1620054 !!

更新的代码是:

echo "/VAULT14/620100_V14/620054 VOL1620054" | awk '{ if (substr($1,(length($1)-5)) == substr($2,(length($2)-5))) print "Same"; else print "Different" }'

3 个答案:

答案 0 :(得分:3)

使用与perl兼容的正则表达式\d{6}\b在单词的末尾(或字符串的结尾)找到6位数字

while read line; do
    set -- $(grep -oP '\d{6}\b' <<< "$line")
    if (( $1 == $2 )); then
        echo "same -- $line"
    else
        echo "diff -- $line"
    fi
done << END
/VAULT14/620100_V14/620054 VOL1620054
/VAULT14/620100_V14/620054 VOL1620541
END
same -- /VAULT14/620100_V14/620054 VOL1620054
diff -- /VAULT14/620100_V14/620054 VOL1620541

答案 1 :(得分:2)

你想要这样的东西:

egrep '([0-9]{6}\>).*\1$' <file>

答案 2 :(得分:2)

Pure bash解决方案:

#!/bin/bash

while read line; do
    if [[ $line =~ /([0-9]{6})[\ \t]+VOL[0-9]*([0-9]{6}) ]] && \
        [[ ${BASH_REMATCH[1]} = ${BASH_REMATCH[2]} ]]; then
        echo same:$line
    else
        echo different:$line
    fi
done

另存为例如2match,然后chmod +x 2match,然后运行:

$ cat vault.txt 
/VAULT14/620100_V14/620054 VOL1620054
/VAULT14/620100_V14/620054 VOL1620541
$ ./2match < vault.txt 
same:/VAULT14/620100_V14/620054 VOL1620054
different:/VAULT14/620100_V14/620054 VOL1620541
$ 

正则表达式可能比它需要的要复杂得多 - 我不确定输入行的格式有多大的灵活性。

显然你可以将echo语句改为你想要的任何东西 - 我只是打印出相同/不同的和完整的行进行检查。