Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a very short Bash script, like this:

variable="3 things"
if $(echo $variable|grep "^[0-9]\{1,\}") #if $variable begins with [0-9]
then
    echo $(echo $variable|sed 's/ .*$//')
else
    echo "0"
fi

$variable will eventually be the output of a command which will be a string beginning with either a number or the word "No ". I want the script to return just the number or else the digit 0.

I'm getting the error, script.bash: line 2: 3: command not found and I don't understand why bash is trying to execute "3" as a command. Any insight would be appreciated (or suggestions on better ways to write this---I'm not good with bash script).

Thanks

share|improve this question
    
As an aside, your regex is either more complex or less complex than it needs to be. Just plain ^[0-9] will match every line that your ^[0-9]\{1,\} will match. Maybe you want to limit matches to those where a space follows the digits? If so, try ^[0-9]\{1,\} (note the trailing space). –  Chris Johnsen Apr 28 '11 at 3:51
add comment

2 Answers 2

up vote 3 down vote accepted

Try this:

variable="3 things"
if echo "$variable" | grep "^[0-9]\{1,\}" >/dev/null 2>&1 #if $variable begins with [0-9]
then
    echo "$variable" | sed 's/ .*$//'
else
    echo "0"
fi

When using the $(...) notation, you are executing the inside command and placing it's output in it's place. The directive if runs the output of that and sees if it is successful. In this case, you really want to test the success of the command you put inside the $(...). It's also good to quote variables when used.

share|improve this answer
    
@penguin259: That works perfectly. I guess I got confused about how to use if vs $(...), and testing return values (basically I was trying to test whether grep returned anything or not). Thanks! –  Wolf Apr 28 '11 at 1:50
1  
@Wolf, in that case, use grep -q .... –  glenn jackman Apr 28 '11 at 2:38
    
@Glenn I used redirection as that is more portable. Some greps don't support -q or treat it as -s. –  penguin359 Apr 28 '11 at 3:02
    
@Wolf Here's some more explanatin. A pipe is a type of complex COMMAND combining mutliple simple COMMANDs in a pipeline. When using multiple simple commands together in a pipe, the return status of the whole pipe is equal to the greatest return status of any individual simple command. Basically that means a pipe is only considered successful if every command was successful. The full syntax of if is if COMMAND1; then COMMAND2; ...; elif COMMAND3; then COMMAND4; ..; else COMMAND5; fi The ; can be replaced by a newline. Basically, if COMMAND1 is successful, COMMAND2 is executed an so on –  penguin359 Apr 28 '11 at 3:08
    
nice answer, but this would be more readable: if [[ "$variable" =~ ^[0-9]\{1,\} ]] –  Kim Apr 28 '11 at 5:30
show 4 more comments

Your script is not trying to execute your variable.
It is trying to execute the output from 'grep'...
The reason it is attempting to execute 3, is for the same reason as when if command is encountered in the script.. The command's is run and its exit code is tested by if.. Your grep output presents if 3 to bash.

if command ;then do-something; fi is okay because if tests the exit code of command.
if 3 ; then do-somethin; fi will fail, because 3 isn't a command... Here is a simple example to indicate if command...

function error() { return 1 ; }
if error  ;then echo A-cond1 ; else echo A-cond2 ;fi
if echo -n;then echo B-cond1 ; else echo B-cond2 ;fi
# `if 3` fails as you already know..
# output:
A-cond2
B-cond1

You can easily avoid all that, and let 'sed' handle the condition tests and the output.

for var in \
  "3 things" \
  " 1 leading space" \
  "10 green bottles" \
  "albatross"
do 
  echo "$var" |sed -e "s/^\([0-9]\+\).*/\1/" \
                   -e "s/^[^0-9].*/0/"
done

Output:

3
0
10
0
share|improve this answer
add comment

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.