Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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
fi

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?

TIA,

Bob

share|improve this question
    
Thanks womble. I wan't aware that we could use regex directly in the IF statment. It worked. I found good references on the following links: tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF –  Bob Rivers Nov 20 '09 at 13:22

3 Answers 3

up vote 3 down vote accepted

Awk is the wrong solution here. How about:

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

There's also a sneaky substitution method:

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

But I find that to be far less readable.


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

case $task in
  Clean*)
    echo hello
    ;;
esac

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.

share|improve this answer
    
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
fi

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

share|improve this answer
    
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
fi

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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