如何在bash中grep一个字符串直到循环



我正在编写一个压缩文件的脚本。我想做一个"直到循环",直到变量的内容与模式匹配。脚本正在使用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"开头的字符串。

图案可以吗?

$ 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

不要忘记表达式中的<<<,您不是在输入文件,而是在输入字符串。为了更符合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:nn$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有用得多。

您不希望在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

相关内容

  • 没有找到相关文章

最新更新