How to grep a string in until loop in bash?

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:

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'.

Is the pattern ok?

Answers


$ 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:

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.


You don't want the back-quotes in the until line. You might write:

until grep -E "$pattern" "$part"
do
    ...body of loop...
done

Or you might add arguments to grep to suppress the output (or send the output to /dev/null). As written, the script tries to execute the output of the grep command and use the success/failure status of that (not the grep per se) as an indication of whether to continue the loop or not.

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 part is well-formed after writing it in Zenity entry dialog. I just realised that grep needs a file, but my part is a variable initialised in this script. How to get along now?

In bash, you can use the <<< operator to redirect from a string:

until grep -E "$pattern" <<< "$part"

In most other shells, you'd write:

until echo "$part" | grep -E "$pattern"

This also works in bash, of course.


Need Your Help

Why is my query doing a clustered index scan when it has an index

sql indexing sql-server-2012 non-clustered-index

I am running a sample database from a SQL Server 2012 training book, learning a bit about indexes so I thought I'd try and see how it works.

Info box for Bing Maps

javascript web-applications bing-maps

I am currently working on a bing maps application and I can't seem to get the info box to appear when the user clicks on the pin. I have been following the SDK and It should be almost exactly the s...