![入力に@が含まれているかどうかを確認するbashスクリプト](https://rvso.com/image/1048309/%E5%85%A5%E5%8A%9B%E3%81%AB%40%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8Bbash%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88.png)
こんにちは。入力に @ 記号が含まれているかどうかをチェックする bash スクリプトを書こうとしています。私は bash の初心者なので、どんな間違いでもお許しください。これまでのところ、次のとおりです。
var1="@"
var2="INPUT"
echo "input"
read INPUT
if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
答え1
組み込みのシェル機能を使用してユーザーの入力が含まれているかどうかを確認するオプションがありますが@
(他の回答で詳しく説明されています)、別の合理的な方法は外部のgrep
ユーティリティ:
#!/usr/bin/env bash
read -erp '> '
if grep -q @ <<<"$REPLY"; then
echo pass
else
echo fail
fi
-q
フラグを渡すとgrep
、一致する行が印刷されなくなります。(また、一致が見つかった後にそれ以上の行を読み取らないようにもなりますが、ここでは入力が 1 行しかないため、違いはありません。)
if
構造を のように短縮したくなりますgrep -q @ <<<"$REPLY" && echo pass || echo fail
が、私は意図的にそれを避けました。
- この場合間違った単語が印刷される唯一の方法は、
pass
印刷されるべきだったがecho
印刷に失敗した場合にのみなので、おそらく問題ありません。その場合、echo も印刷に失敗するでしょうfail
。 - 短絡
&&
や||
それ自体は適切であることが多い(そして私はよくそれらを略語として使う)が、if
それなし節else
)のように一緒に使用する。三元もしオペレーターあまり良い習慣とは言えません。一部のコマンドは失敗、echo
できる。 - ユーザーがリダイレクトスクリプトの出力を書き込み不可能なファイルやデバイスに書き込んだり、壊れたパイプライン、echo などのテキストを出力するコマンドは失敗を返す可能性があり、その場合、
&&
式は失敗し、式の右側が||
実行されます。 - 書き込み不可能な出力デバイスがある場合のスクリプトの動作を、 で実行することでテストできます
>/dev/full
。
このスクリプトでは、いくつかの bash 機能を使用します。
-e
GNU readline を有効にすると、ユーザーは矢印キーを使用してカーソルを左右に移動し、入力中に入力内容を編集できるようになります。- bash では、変数が指定されていない場合、
read
ユーザーの入力が自動的に変数に格納されます。REPLY
- あここで文字列は、
<<<
ユーザーの入力を に渡す便利な方法ですgrep
。 - バッシュといくつかのdashなどの他のBourneスタイルのシェルは受け入れます
-p
。しかしPOSIX互換シェルは、-r
. また、kshのように、-p
別の意味を持つものもあります。
(ゲイラ両方のことを指摘してくれた-p
時々欠けているそして必ずしも「迅速」を意味するわけではありません。)
bash がインストールされていない可能性のある他の OS に移植可能なスクリプトが必要な場合は、次を使用できます。
#!/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
コードは入力を読み取り、入力に@
シンボルが含まれている場合は「Pass」を通知します。
read -p "Input: " var
[ "${var//[^@]/}" ] && echo Pass || echo Fail
ノート:
[ "$var" ]
bash テストです。文字列$var
が空でない場合は true を返します。bashの機能の1つにパターン置換があります。 のように見えます。のすべての出現をに
${var//pattern/string}
置き換えます。この場合、はすべての文字に一致する正規表現です。pattern
var
string
pattern
[^@]
を除外する@
. したがって、少なくとも 1 つの が含まれてい${var//[^@]/}
ない場合は空の文字列を返します。var
@
上記の 2 つを組み合わせます。
[ "${var//[^@]/}" ]
このテストは、
${var//[^@]/}
が空でない場合にのみ成功し、に少なくとも 1 つの が含まれている${var//[^@]/}
場合にのみ空でなくなります。var
@
明示的な if-then-else を使用する:
read -p "Input: " var
if [ "${var//[^@]/}" ]
then
echo Pass
else
echo Fail
fi
POSIX シェル
以下はdash
( /bin/sh
) の下で動作し、どの POSIX シェルの下でも動作するはずです。
printf "Input: "
read var
case "$var" in
*@*) echo Pass
;;
*) echo Fail
;;
esac
POSIXシェルは-p
オプションをサポートしていませんread
printf
したがって、代わりにとの組み合わせread
が使用されます。また、 の高度な変数拡張機能がないためbash
、case
ステートメントはグロブ マッチングに使用できます。
Android シェル
Android のデフォルト シェルを使用すると、次のように動作します。
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 準拠のシステムであればどこでも動作する代替案としては、シェル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
$