ファイル名を求める関数を作成しています。その後、入力がアルファベット文字で始まっていることを確認し、そうでない場合は、条件が満たされるまでユーザーに名前を再入力するように求められます。また、ユーザーがパスを入力すると、追加のメッセージが表示されます(この割り当ての目的に応じて、パスは「/」を含むすべてのエントリです)。これが私が経験している問題です...
これは私のコードです...
#1) make a getname function that will prompt for filename
function getname(){
trap control_c SIGINT
local fname=$1;
#if there is no input prompt user for file name
if [ ! $1 ]; then
read -p "Enter a file name: " fname;
fi;
#until grep is given a valid file name
until ( grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1); do
#this is were the error is
if echo "$fname" | grep -E '/';
then #this tests if fname is a file directory
echo "Paths are not a legal file name.";
fi;
read -p "Enter a legal file name: " fname;
done
echo "$fname"
}
Until ループの if ステートメントは、どのような状況でも、ユーザーにパスが有効な入力ではないというメッセージを表示せず、エラーを生成しません。 if文でgrepを正しく実装する方法は?
答え1
実際、Fedora 26ではこの機能が機能します。GNU bash, version 4.4.12(1)-release (x86_64-redhat-linux-gnu)
この関数はパスが提供されているかどうかを尋ねます。出力を表示します。
[@host testing]$ getname
Enter a file name: ab/sav
ab/sav
Paths are not a legal file name.
Enter a legal file name: abc
abc
[@host testing]$
しかし、2つの小さな問題を発見しました。まず、パスを印刷してから再入力を要求します。この問題は、grep -q
ステートメントのスイッチ(静かさを意味するq)を使用して解決できますif
(また、適用され、until
出力リダイレクトはもはや必要ありません)。第二に、ループ内では個々の文字は常に有効ではありませんuntil
。この問題は\w+
正規表現を変更することで解決できます\w*
。
答え2
grep
ステートメントが非常に大きくなるまで単純化できます。
私は次のアプローチを提案できます。
until [ ! -z "$fname" ]; do
read -p "Enter a legal file name: " fname
grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1
#check exit code
if [ $? -ne 0 ]; then
echo "Paths are not a legal file name."
fname=""
fi
done
必要に応じて、Untilループ内に他の条件を関連付けることができます。
ユーザーのメッセージを処理するには、read
複数のコマンドを提示しなくてもこのトリックを使用できます。
fname=""
message_for_user="Enter a file name: "
until [ ! -z "$fname" ]; do
read -p "$message_for_user" fname
grep -E '^[a-zA-Z_]\w+$' <<< "$fname" > /dev/null 2>&1
#check exit code
if [ $? -ne 0 ]; then
echo "Paths are not a legal file name."
fname=""
message_for_user="Enter a legal file name: "
fi
done
出力は次のとおりです。
Enter a file name: 1laha
Paths are not a legal file name.
Enter a legal file name:
1行目と3行目は異なります。
答え3
if
ステートメントで直接正規表現を使用できます。
if [[ $name =~ ^[a-zA-Z] ]]
または:
if [[ $name =~ ^[:alpha:] ]]