2

如果我有

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

4 回答 4

5

我通常将-fgrep 的标志用于类似目的。<( ... )代码生成一个包含所有可能性的文件,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]' )
于 2013-05-21T12:42:17.783 回答
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然后在读取一行时,获取最后一个数字,如果它存在于数组中,然后从数组中删除它。所以最后,在数组中,只剩下那些没有找到的元素。排序只是以排序的方式呈现:)

于 2013-05-21T13:03:38.833 回答
2
F=$(func)

for f in $days; do
    if ! echo $F | grep -q lSecure$f; then
    echo lSecure$f
    fi
done
于 2013-05-21T13:04:05.583 回答
1

我不确定您到底要达到什么目的,但您可能会考虑使用uniq -uwhich 删除重复的序列。例如,您可以使用它来执行此操作:

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

输出:

2
3
5
于 2013-05-21T13:20:25.467 回答