如何生成与模式不匹配的字符串元素?

时间:2013-05-21 12:32:03

标签: linux bash awk grep

如果我有

days="1 2 3 4 5 6"

func() {
    echo "lSecure1"
    echo "lSecure"
    echo "lSecure4"
    echo "lSecure6"
    echo "something else"
}

并做

func | egrep "lSecure[1-6]"

然后我得到

lSecure1
lSecure4
lSecure6

但我想要的是

lSecure2
lSecure3
lSecure5

这是没有lSecure字符串的所有日子。

问题

我目前的想法是使用awk拆分$days,然后循环遍历所有组合。

有更好的方法吗?

请注意,grep -v会反转普通grep的意义,并且不能解决问题,因为它不会生成所需的字符串。

4 个答案:

答案 0 :(得分:5)

我通常使用grep的-f标志来达到类似的目的。 <( ... )代码生成一个包含所有可能性的文件,grep只选择那些不存在于func中的文件。

func | grep 'lSecure[1-6]' | grep -v -f- <( for i in $days ; do echo lSecure$i ; done )

或者,您可能更喜欢它反过来:

for i in $days ; do echo lSecure$i ; done | grep -vf <( func | grep 'lSecure[1-6]' )

答案 1 :(得分:2)

awk解决方案:

$ func | awk -v i="${days}" 'BEGIN{split(i,a," ")}{gsub(/lSecure/,"");
                             for(var in a)if(a[var] == $0){delete a[var];break}} 
                             END{for(var in a) print "lSecure" a[var]}' | sort

我们将它存储在一个awk数组a中,然后在读取一行时,获取最后一个数字,如果它存在于数组中,则从数组中删除它。所以最后,在数组中,只剩下那些尚未找到的元素。排序只是以排序的方式呈现:)

答案 2 :(得分:2)

F=$(func)

for f in $days; do
    if ! echo $F | grep -q lSecure$f; then
    echo lSecure$f
    fi
done

答案 3 :(得分:1)

我不确定您要实现的目标,但您可以考虑使用删除重复序列的uniq -u。例如,您可以使用它来执行此操作:

( echo "$days" | tr -s ' ' '\n'; func | grep -oP '(?<=lSecure)[1-6]' ) | sort | uniq -u

输出:

2
3
5