我在编写压缩文件的脚本。我想做一个'until loop'直到'变量的内容与模式匹配。该脚本使用zenity。这是主要部分:
part="0"
pattern="^([0-9]{1}[0-9]*([km])$"
until `grep -E "$pattern" "$part"` ; do
part=$(zenity --entry \
--title="Zip the file" \
--text "Choose the size of divided parts:
(0 = no division, *m = *mb, *k = *kb)" \
--entry-text "0");
if grep -E "$pattern" "$part" ; then
zenity --warning --text "Wrong text entry, try again." --no-cancel;
fi
done
我希望它接受包含以'k'或'm'结尾的数字的字符串(但不是两者都有),并且不接受以'0'开头的字符串。
模式是否正常?
答案 0 :(得分:5)
$ grep -w '^[1-9][0-9]*[km]$' <<< 45k
45k
$ grep -w '^[1-9][0-9]*[km]$' <<< 001023m
$ grep -w '^[1-9][0-9]*[km]$' <<< 1023m
1023m
不要忘记你的表达式中的<<<
,你不是grep一个文件,而是一个字符串。要更符合POSIX,您还可以使用:
echo 1023m | grep -w '^[1-9][0-9]*[km]$'
但它有点难看。
修改强>:
更长的例子:
initmessage="Choose the size of divided parts:\n(0 = no division, *m = *mb, *k = *kb)"
errmessage="Wrong input. Please re-read carefully the following:\n\n$initmessage"
message="$initmessage"
while true ; do
part=$(zenity --entry \
--title="Zip the file" \
--text "$message")
if grep -qw '^[1-9][0-9]*[km]$' <<< "$part" ; then
zenity --info --text 'Thank you !'
break
else
message="$errmessage"
fi
done
此外,这与问题没有直接关系,但您可能需要查看Yad,这与Zenity的功能基本相同,但有更多选项。当我不得不编写Bash脚本时,我经常使用它,并发现它比Zenity更有用。
答案 1 :(得分:3)
您不希望until
行中的后引号。你可以写:
until grep -E "$pattern" "$part"
do
...body of loop...
done
或者您可以向grep
添加参数以抑制输出(或将输出发送到/dev/null
)。如上所述,脚本尝试执行grep
命令的输出并使用其成功/失败状态(不是grep
本身)作为是否继续循环的指示。
此外,您的模式需要一些工作。它是:
pattern="^([0-9]{1}[0-9]*([km])$"
那里有一个无与伦比的开括号。它也让我看起来好像它试图允许领先的零。你可能想要:
pattern='^[1-9][0-9]*[km]$'
单引号通常比正则表达式之类的双引号更安全。
我只是想在Zenity条目对话框中写完后,检查名为
part
的变量是否格式正确。我刚刚意识到grep
需要一个文件,但我的part
是在这个脚本中初始化的变量。如何相处?
在bash
中,您可以使用<<<
运算符从字符串重定向:
until grep -E "$pattern" <<< "$part"
在大多数其他shell中,你会写:
until echo "$part" | grep -E "$pattern"
当然,这也适用于bash
。