2013-05-21 42 views
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的意義,並沒有解決問題,因爲它不會生成所需的字符串。

+1

@fedorqui:閱讀問題。扭轉grep的感覺不答應它。 – Vicky

+0

您是否試圖通過在每個'$ day'的每個元素上添加來生成字符串?到目前爲止,你的'func'只能迴應你的內容。 –

+0

@fedorqui,我在大聲呼喊,因爲你的第三個建議是使用-v,我剛剛評論過(現在刪除了一個答案,在撰寫評論時還有一個答案,然後是你的評論),我覺得當沒有人真正閱讀這個問題時,對OP抱歉。 – Vicky

回答

1

我不知道你想實現什麼,但你可能會考慮使用uniq -u它刪除重複序列。例如,你可以用它做:

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

輸出:

2 
3 
5 
+0

當我嘗試第一個管道給出'語法錯誤:意外重定向' –

+0

您正在使用哪個版本的'bash'?你可以通過用'echo'$ days「|替換'tr'來使它更便於攜帶tr'''\ n''。 – Thor

+0

@SandraSchlichting:看到編輯,我讓示例更加便攜。 – Thor

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]') 
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
F=$(func) 

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

這會一次又一次地調用func。所以如果func有任何累積的副作用,那會破壞你的主要目的:) – abasu

+0

現在更新它,所以它只被調用一次=) –

+0

使用簡單而優雅的方法的好解決方案:) +1對於那個 – abasu