bash腳本檢查輸入是否有@

bash腳本檢查輸入是否有@

您好,我正在嘗試編寫一個 bash 腳本,其中檢查輸入以查看它是否包含 @ 符號,我對 bash 比較陌生,所以請原諒任何/所有錯誤!到目前為止我有:

var1="@"
var2="INPUT"

echo "input"
read INPUT

if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi

答案1

儘管您可以選擇使用內建的 shell 功能來檢查使用者的輸入是否包含@(其他答案中有詳細記錄),但另一種合理的方法是使用外部grep公用事業:

#!/usr/bin/env bash

read -erp '> '
if grep -q @ <<<"$REPLY"; then
    echo pass
else
    echo fail
fi

傳遞-q標誌以grep防止它列印匹配的行。 (它還可以防止它在找到匹配項後讀取更多行,但這並沒有什麼區別,因為只有一行輸入。)

if將構造縮短為類似的東西很誘人grep -q @ <<<"$REPLY" && echo pass || echo fail,但我故意避免這樣做:

  • 在這種情況下,這可能沒問題,因為列印錯誤單字的唯一方法是如果pass應該列印但echo未能列印它。那麼,echo 可能fail也無法列印。
  • 雖然短路&&||通常本身是合適的(我經常使用它們來縮寫if 沒有一個else子句),將它們一起使用,就好像它們是三元如果操作員這確實不是一個好習慣。雖然有些命令不能失敗,echo
  • 如果用戶重定向您的腳本的輸出到不可寫入的檔案或設備,或在損壞的情況下使用它管道、echo 等輸出文字的命令可能會傳回失敗,導致表達式失敗並執行表達式&&的右側。||
  • 您可以透過使用 執行腳本來測試腳本在存在不可寫入輸出裝置的情況下的行為>/dev/full

腳本使用了一些 bash 功能:

如果您想要一個可移植到可能未安裝 bash 的其他作業系統的腳本,您可以使用:

#!/bin/sh

printf '> '
read -r line

if printf '%s' "$line" | grep -q @; then
    echo pass
else
    echo fail
fi

如果您願意,您可以透過讀取使用者的輸入來跳過將使用者的輸入儲存在變數中head代替read

#!/bin/sh

printf '> '
if head -1 | grep -q @; then
    echo pass
else
    echo fail
fi

作為蓋爾哈提到,可能被認為是head -n 1更好的語法head -1正式過時(儘管當前的sed實現,或至少是 GNU sed,-1在其最新版本中支持,而一些非常舊的sed實現不支持-n 1)。

作為head文件說,您可以使用sed它來獲得最大的便攜性。

#!/bin/sh

printf '> '
if sed 1q | grep -q @; then
    echo pass
else
    echo fail
fi

答案2

bash代碼讀取輸入並在輸入包含符號時發出“通過”信號@

read -p "Input: " var
[ "${var//[^@]/}" ] && echo Pass || echo Fail

筆記:

  • [ "$var" ]是一個 bash 測試。如果字串$var非空, 則傳回 true 。

  • bash 的功能之一是模式替換。看起來像${var//pattern/string}。它將每次出現的patternin替換varstring。在我們的例子中,patternis[^@]是一個符合每個字元的正規表示式除了 @。因此${var//[^@]/}傳回一個空字串,除非var至少包含一個@

  • 我們將上面兩者結合起來:

    [ "${var//[^@]/}" ]
    

    僅當${var//[^@]/}為非空時,此測試才會成功,且僅當包含至少一個時,此測試${var//[^@]/}才為非空。var@

使用顯式的 if-then-else:

read -p "Input: " var
if [ "${var//[^@]/}" ]
then
    echo Pass
else
    echo Fail
fi

POSIX 外殼

以下內容在dash( /bin/sh) 下工作並且應該在任何 POSIX shell 下工作:

printf "Input: "
read var
case "$var" in
    *@*) echo Pass
        ;;
    *) echo Fail
        ;;
esac

POSIX shell 不支援-p下列選項read。因此,使用printf和的組合read來代替。此外,由於缺乏 的高階變數擴充功能bash,此case語句可用於全域匹配。

安卓外殼

使用我的 Android 上的預設 shell,可以執行以下操作:

echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
    echo Pass
else
    echo Fail

答案3

bash 中的首選方法是使用 的模式匹配功能[[ ... ]]

#bash
read -rp "Input: " input
if [[ $input = *@* ]]; then
    printf '<%s> contains @\n' "$input"
fi

對於sh腳本,您可以case改為使用。

#sh
printf 'Input: '
read -r input
case $input in
    *@*) printf '<%s> contains @\n' "$input" ;;
esac

另請參閱測試和條件Bash 指南的章節。

答案4

在較新版本的 bash 中,您應該能夠使用正規表示式匹配透過=~擴展測試運算符:

$ read -p "input: " input
input: quertyuiop 
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
no match
$ 
$ read -p "input: " input
input: qwerty@uiop
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
match

應該在任何 POSIX 相容系統中工作的替代方法是在 shell 中使用expr例如dash

$ read input
qwertyuiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
no match
$ 
$ read input
qwerty@uiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
match
$ 

相關內容