2016-03-01 49 views
0

我正在使用bash編寫腳本,它將提示用戶輸入兩個輸入。這些輸入分別分配給變量「TO_SCHEMA」和「FROM_SCHEMA」。如何清理Bash中的用戶輸入

我需要一種方法來驗證正確的輸入。我的要求如下:

每個變量將有3個可接受的值。它們對於這兩個變量都是相同的值,但是這兩個變量都必須在三個列表中,並且它們不能是相同的值。

因此,如果值是'myco','myco_int'和'teambatch',那麼這兩個變量必須是其中的一個值,但它們不能相同。

${TO_SCHEMA} = myco && ${FROM_SCHEMA} = myco_int 
    Pass 

${TO_SCHEMA} = myco_int && ${FROM_SCHEMA} = myco_int 
    Fail 

${TO_SCHEMA} = mco && ${FROM_SCHEMA} = myco_int 
    Fail 

${TO_SCHEMA} = myco && ${FROM_SCHEMA} = donkey 
    Fail 

我該如何做到這一點?

我從一個充滿AND和OR操作符的if語句開始,但它們變得很難看。我在正則表達式方面的經驗有限,而我對sed和awk的經驗並不存在,但我願意學習並嘗試其中的任何一點。 任何幫助,將不勝感激。

編輯:

我還要提到的是這個腳本僅僅是一個有點小繁瑣的一次性的任務,我必須做很多的,我很想自動化工作。如果我不是使用它的人,那麼我的團隊中會有人。所以這個輸入檢查是一個需要,而不是一個需要。如果腳本因輸入錯誤而中斷,那麼世界並不是世界末日。我只想讓它更優雅地處理不好的輸入。

編輯再次: 我感謝大家的建議,但我必須做出一些澄清。這些值實際上不是模式1,2和3.我不允許出於安全原因提供正確的名稱,但是我將它們更改爲與真實名稱更類似的值。

+0

家庭作業嗎? – Lizardx

+0

......如果我把事情做對了,那麼可能的組合列表就非常有限。所以可能你應該只是代表這些列表並讓用戶選擇。 – mikyra

+0

@ Lizardx哈哈,不是一項家庭作業。只是一個傷心的SE,他以前沒有做過很多腳本,但這會是一個很好的簡單腳本,它會爲我節省很多時間,並讓其他人完成任務,如果我遇到公共汽車什麼的。 – Simoney

回答

1

最簡單的解決方案需要bash 4.3。您只需將有效輸入存儲爲關聯數組的鍵,然後使用-v運算符來檢查給定輸入是否被定義爲鍵。

declare -A valid 
# Values don't matter, as long as the key exists. 
# I put spaces in the keys just to show it's possible 
valid[schema 1]= 
valid[schema 2]= 
valid[schema 3]= 

if [[ $FROM_SCHEMA != $TO_SCHEMA && -v valid[$FROM_SCHEMA] && -v valid[$TO_SCHEMA] ]]; then 
    # inputs pass 
else 
    # inputs fail 
fi 

在之前的4.x版本中,您可以稍微不同地檢查關聯數組中的未定義值。

declare -A valid 
# Now, we need to make sure the values are non-null, but 
# otherwise it doesn't matter what they are 
valid[schema 1]=1 
valid[schema 2]=1 
valid[schema 3]=1 
if [[ $FROM_SCHEMA != $TO_SCHEMA && -n ${valid[$FROM_SCHEMA]} && -n ${valid[$TO_SCHEMA]} ]]; then 
    # inputs pass 
else 
    # inputs fail 
fi 

之前bash 4,沒有關聯數組,可以回退到掃描存儲在規則陣列有效輸入列表。

valid=("schema 1" "schema 2" "schema 3") 
if [[ $TO_SCHEMA == $FROM_SCHEMA ]]; then 
    # inputs fail 
else 
    ok_count=0 
    # We've already established that TO and FROM are different, 
    # so only at most one per candidate can match. 
    for candidate in "${valid[@]}"; do 
     if [[ $TO_SCHEMA == $candidate || $FROM_SCHEMA == $candidate ]]; then 
      ok_count+=1 
     fi 
    done 
    if ((ok_count == 2)); then 
     # inputs pass 
    else 
     # inputs fail 
    fi 
fi 
+0

這幾乎是我正在尋找的東西。我知道我本可以想辦法做到這一點,但我希望能以實用的代碼高效的方式獲得幫助。我會測試一下,明天哪個效果最好。謝謝! – Simoney

+0

因爲我們沒有使用最新版本的bash,所以我不得不與2號門合作,但它的工作原理!謝謝! – Simoney

0

請注意,快速和骯髒,缺乏優雅,但工程。這假設您的schema1答案是準確的。而且我正確地閱讀你的問題。你會用你從哪裏獲取數據來替換[你的輸入1]等,這是對用戶輸入的讀取權?爲什麼不要讓他們從列表中選擇它?

values='1 2 3' 
result1='' 
result2='' 

input1=[your input 1] 
input2=[your input 2] 
# force to lower case 
input1=$(tr '[A-Z]' '[a-z]' <<< "$input1") 
input2=$(tr '[A-Z]' '[a-z]' <<< "$input2") 

for item in $values 
do 
    if [[ -n $(grep -E "^schema$item$" <<< $input1) ]];then 
     values=$(sed "s/$item//" <<< $values) 
     result1=$input1 
    fi 
done 
for item in $values 
do 
    if [[ -n $(grep -E "^schema$item$" <<< $input2) ]];then 
     result2=$input2 
    fi 
done 

if [[ -z $result1 ]];then 
    echo 'Your first entry is not right: ' $input1 
elif [[ -z $result2 ]];then 
    echo 'Your second entry is not right: ' $input2 
else 
    echo 'Valid data' 
fi 

請注意,如果你想只測試文字滿弦,你會做它:

values='schema1 schema2 schema3' 

然後從grep的測試,然後這只是看起來去掉「模式」爲完整的字符串的東西。而sed會從值列表中刪除找到的項目。

如果您依賴用戶鍵入的輸入,則必須強制降低以避免痙攣的用戶操作,或者執行與grep不區分大小寫的模式匹配,但最好在測試之前強制降低它。

input1=$(tr '[A-Z]' '[a-z]' <<< "$input1") 
+0

哇,這是....我有很多谷歌搜索做。儘管感謝您的輸入!它看起來比我想要提出的任何案例陳述更好。當我明天回去工作時,我會進一步探索這個解決方案。 – Simoney

+0

這個邏輯很容易理解,但也許不容易閱讀。您從數字列表開始,字符串部分是靜態的,如果不是,您只需替換值列表中的文字。然後你測試輸入,理想地修剪空格等,是'schema'+ [數字]的精確匹配。如果匹配,則從第一次測試中找到該數字,然後從可能值列表中刪除數字。在第二個測試中,您只需看看該字符串+數字是否存在於第二個測試中。由於第一次測試刪除了找到的號碼,因此您只剩下未找到的號碼。 – Lizardx