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

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.