如果我有
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的意义,并且不能解决问题,因为它不会生成所需的字符串。
答案 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