bash 如何在bash中的直到循环中grep字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16341609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to grep a string in until loop in bash?
提问by Nojas
I work on a script compressing files. I want to do an 'until loop' til' the content of variable matches the pattern. The script is using zenity. This is the major part:
我正在处理一个压缩文件的脚本。我想做一个“直到循环”直到变量的内容与模式匹配。该脚本正在使用 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
I want it to accept string containing digits ended with 'k' or 'm' (but not both of them) and don't accept string started with '0'.
我希望它接受包含以 'k' 或 'm' 结尾的数字的字符串(但不是两者),并且不接受以 '0' 开头的字符串。
Is the pattern ok?
图案好吗?
回答by michaelmeyer
$ 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
Don't forget the <<<in your expression, you're not grep'ing a file, but a string. To be more POSIX-compliant, you can also use:
不要忘记<<<表达式中的 ,您不是在搜索文件,而是字符串。为了更符合 POSIX,您还可以使用:
echo 1023m | grep -w '^[1-9][0-9]*[km]$'
But it is kinda ugly.
但它有点丑。
Edit:
编辑:
Longer example:
更长的例子:
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
Also, this is not directly related to the question, but you may want to have a look at Yad, which does basically the same things Zenity does, but has more options. I used it a lot when I had to write Bash scripts, and found it much more useful than Zenity.
此外,这与问题没有直接关系,但您可能想看看Yad,它与 Zenity 所做的事情基本相同,但有更多选择。我在编写 Bash 脚本时经常使用它,发现它比 Zenity 有用得多。
回答by Jonathan Leffler
You don't want the back-quotes in the untilline. You might write:
您不希望该行中出现反引号until。你可能会写:
until grep -E "$pattern" "$part"
do
...body of loop...
done
Or you might add arguments to grepto suppress the output (or send the output to /dev/null). As written, the script tries to execute the output of the grepcommand and use the success/failure status of that (not the grepper se) as an indication of whether to continue the loop or not.
或者您可以添加参数以grep抑制输出(或将输出发送到/dev/null)。正如所写,脚本尝试执行grep命令的输出并使用它的成功/失败状态(而不是grep本身)作为是否继续循环的指示。
Additionally, your pattern needs some work. It is:
此外,您的模式需要一些工作。这是:
pattern="^([0-9]{1}[0-9]*([km])$"
There is an unmatched open parenthesis in there. It also looks to me as though it is trying to allow a leading zero. You probably want:
那里有一个无与伦比的开括号。在我看来,它也好像试图允许前导零。你可能想要:
pattern='^[1-9][0-9]*[km]$'
Single quotes are generally safer than double quotes for things like regular expressions.
对于正则表达式之类的东西,单引号通常比双引号更安全。
I just want to check if my variable called
partis well-formed after writing it in Zenity entry dialog. I just realised thatgrepneeds a file, but mypartis a variable initialised in this script. How to get along now?
part在 Zenity 输入对话框中写入后,我只想检查我调用的变量是否格式正确。我刚刚意识到grep需要一个文件,但我part是在此脚本中初始化的变量。现在怎么相处?
In bash, you can use the <<<operator to redirect from a string:
在 中bash,您可以使用<<<运算符从字符串重定向:
until grep -E "$pattern" <<< "$part"
In most other shells, you'd write:
在大多数其他 shell 中,您会这样写:
until echo "$part" | grep -E "$pattern"
This also works in bash, of course.
bash当然,这也适用于。

