私はUNIXを初めて使用し、今日は仕事を始めたばかりですが、Javaの経験があり、次のコードを使用しています。
#/bin/bash
echo "Please enter a Word:"
read Word
grep -i $Word $1 | cut -d',' -f1,2 | tr "," "-"> output
これは問題なく動作しますが、Wordを読み取るときに、文字だけが含まれていること、および「無効な入力!」という文字が印刷されているかどうかを確認する必要があります。メッセージを送信し、もう一度入力するように依頼します。 ifステートメントを使用した正規表現がこれを行う簡単な方法であると想定しましたが、Javaアプリケーションに慣れているため、UNIXでの使用方法について頭を悩ませることはできません。任意Linuxで正規表現を使用するすべてのソリューションを検索したときにヘルプが見つからなかったため、これを支援していただければ幸いです。すべて数値であるかどうかに関係なく対処できました。
さらに別のアプローチ。一致するものが見つかった場合、Grepは0
で終了するため、終了コードをテストできます。
echo "${Word}" | grep -q '[0-9]'
if [ $? = 0 ]; then
echo 'Invalid input'
fi
これは/bin/sh
と互換性があります。
DaenythとJohnの提案を取り入れると、これは次のようになります。
if echo "${Word}" | grep '[0-9]' >/dev/null; then
echo 'Invalid input'
fi
二重角かっこ演算子は、test
コマンドの拡張バージョンであり、=~
演算子を介して正規表現をサポートします。
#!/bin/bash
while true; do
read -p "Please enter a Word: " Word
if [[ $Word =~ [0-9] ]]; then
echo 'Invalid input!' >&2
else
break
fi
done
これはbash固有の機能です。 Bashは、UNIXのすべてのフレーバーで使用できるわけではない新しいシェルです。ただし、「新しい」とは「真空管後の時代に最近開発されたばかり」を意味し、「UNIXのすべてのフレーバーではない」とは古いバージョンのような遺物を意味します。 SolarisおよびHP-UXの。
私の意見では、これは最も簡単なオプションであり、bashは最近十分に移植可能ですが、古いUNIXに移植可能であることが実際に重要である場合は、他のポスターのsh互換の回答を使用する必要があります。 shは最も一般的で最も広くサポートされているシェルですが、移植性のために支払う代償は=~
のようなものを失っています。
移植可能なシェルコードを作成しようとしている場合、文字列操作のオプションは制限されています。 case
コンストラクトでシェルグロブパターン(正規表現よりも表現力がはるかに低い)を使用できます。
export LC_COLLATE=C
read Word
while
case "$Word" in
*[!A-Za-z]*) echo >&2 "Invalid input, please enter letters only"; true;;
*) false;;
esac
do
read Word
done
[〜#〜] edit [〜#〜]:LC_COLLATE
を設定する必要があります。これは、ほとんどの非C
ロケールでは、A-Z
のような文字範囲に「明らかな」がないためです。 」の意味。 ASCII文字のみが必要だと思います。発音区別符号付きの文字も必要な場合は、LC_COLLATE
を変更せず、A-Za-z
を[:alpha:]
に置き換えてください(したがって、パターン全体が*[![:alpha:]]*
)になります。
完全な正規表現については、expr
コマンドを参照してください。 [〜#〜] edit [〜#〜]:expr
には、他のいくつかの基本的なシェルツールと同様に、いくつかの特別な文字列に関する落とし穴があることに注意してください。以下のz
文字は、$Word
がexpr
によって予約語として解釈されるのを防ぎます。
export LC_COLLATE=C
read Word
while expr "z$Word" : 'z[A-Za-z]*$' >/dev/null; then
echo >&2 "Invalid input, please enter letters only"
read Word
fi
Bashの最近の十分なバージョンのみを対象とする場合は、=~
条件付きコマンドの[[ ... ]]
演算子などの他のオプションがあります。
最後の行にバグがあることに注意してください。最初のコマンドは
grep -i "$Word" "$1"
引用符は、やや直感に反するため、"$foo"
は「foo
という変数の値」を意味しますが、プレーンな$foo
は「foo
の値を取得し、空白を含む別の単語に分割し、各単語をグロブパターンとして扱い、それを拡張してみてください。」 (実際、$Word
に文字のみが含まれていることをすでに確認している場合、引用符を残しても害はありませんが、毎回引用符を付けるよりも、これらの特殊なケースを考えるのに時間がかかります。)
それを行うためのさらに別の(かなり)ポータブルな方法...
if test "$Word" != "`printf "%s" "$Word" | tr -dc '[[:alpha:]]'`"; then
echo invalid
fi
Bashパラメーターの拡張と文字クラスをいじってみましょう。
# cf. http://wiki.bash-hackers.org/syntax/pe
Word="abc1def"
Word="abc,def"
Word=$'abc\177def'
# cf. http://mywiki.wooledge.org/BashFAQ/058 (no NUL byte in Bash variable)
Word=$'abc\000def'
Word="abcdef"
(
set -xv
[[ "${Word}" != "${Word/[[:digit:]]/}" ]] && echo invalid || echo valid
[[ -n "${Word//[[:alpha:]]/}" ]] && echo invalid || echo valid
)
これを行うための1つのポータブルな(bash> = 3と仮定)方法は、すべての数値を削除して長さをテストすることです。
#!/bin/bash
read -p "Enter a number" var
if [[ -n ${var//[0-9]} ]]; then
echo "Contains non-numbers!"
else
echo "ok!"
fi
Javaに由来するため、bashにはオブジェクトやデータ型の実際の概念がないことに注意することが重要です。すべてが文字列であり、複雑なデータ構造はせいぜい苦痛です。
私が行ったことやその他の関連機能の詳細については、Googleでbash文字列を操作してください。
みんなの答えは、無効な文字は数字だけだという事実に基づいているようです。最初の質問では、文字列に「文字以外は何もない」ことを確認する必要があると述べています。
私はそれを行うための最良の方法はだと思います
nonalpha=$(echo "$Word" | sed 's/[[:alpha:]]//g')
if [[ ${#nonalpha} -gt 0 ]]; then
echo "Invalid character(s): $nonalpha"
fi
このページで文字列内の数字以外の文字を検出する方法を探している場合(私が行ったように!)、[[:alpha:]]を[[:digit:]]に置き換えます。