I'm doing a script in which I need to test a string and based on its result I'll decide if I go further or not.

The command below works fine (if the string starts with "Clean" it will print 1, otherwise 0).

echo | awk ' {print index("'"${task}"'", "Clean")}'

What I'm trying to do is to use the AWK with IF in a BASH script. Based on this post I did the following:

idx=$(awk '{print index("'"${task}"'", "Clean")}')
echo $idx
if [ "$idx" == "0" ]; then
   echo hello

As I said, when I run the script it prints "0", but the second "echo" doesn't print anything, and of course the if doesn't works either.

Can anyone help me?




Awk is the wrong solution here. How about:

if [[ "$task" =~ ^Clean ]]; then
  echo hello

There's also a sneaky substitution method:

if [ "${task/#Clean/}" != "$task" ]; then
  echo hello

But I find that to be far less readable.

Chris reckons case is tidier... let's try that out:

case $task in
    echo hello

My aesthetic sense says "hell no with bells on", and fiddling with the formatting (Clean*) echo hello;; or similar) won't help much, IMAO. If you want a conditional, use an if, I say.

  • You can use case for stuff like this; it's typically quite a bit tidier. – chris Nov 17 '09 at 16:45
  • The nice thing about case statements is that they eliminate great big piles of if ; then ; elif ; then ; elif ; then ; else; fi structures, and they have better regular expression matching than test. – chris Nov 17 '09 at 18:15
  • Well, when we get to having lots of if/elif blocks involving the same variable, we can switch to using a case statement. Also, case uses pathname expansion (roughly, globbing), whereas [[ =~ uses actual regular expressions. – womble Nov 17 '09 at 18:28

Womble's answer is probably what I would go for, but you can also use grep:

if echo cleanarf | grep -qi '^clean'; then 
   echo foo

Drop the i switch to grep if you want it case sensitive (or if you do not want it case insensitive :-p ).

  • This is less readable, IMAO, and slower because it involves spawning a separate process. – womble Nov 17 '09 at 16:59
  • Agreed, that is why I said I would opt for your answer :-P But options are good. – Kyle Brandt Nov 17 '09 at 17:03

In your first example, you use echo to provide awk with a file (stdin), but in your script, there is no file for awk to process and it "hangs" waiting for input. You could use echo in your variable assignment in the $(), but I prefer to use /dev/null for this purpose (i.e. when there's no actual file to process).

In order to avoid awkward quoting, you can use variable passing with the -v option to provide Bash variables to an awk script.

You should find that this works:

idx=$(awk -v task="$task" '{print index(task, "Clean")}' /dev/null)
echo $idx
if [ "$idx" == "0" ]; then
   echo hello

You should probably use womble's suggestion, though, since it doesn't require spawning a separate process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.