I have a variable containing a leading zeroes number, and I want to grep this variable and that same variable plus one. I made several attempts but ran into errors. Here's what I want to do:

read var
newvar=$(($var +1))
grep '$var' /some/dir
grep '$newvar' /some/dir

I really think there's something wrong with my code. I also tried some test like this:

echo "enter number"
read number
newnumber=$(($number + 1))
echo "$newnumber"

That gives me an error: value too great for base (error token is. If i do it like this:

echo "enter number"
read number
newnumber=$(($number + 1))
echo "$newnumber"

This will output 1 all the time.

What's wrong with my attempts, and how can I do what I want?

  • 2
    ​@user774187 Please don't edit away a whole chunk of your question, as it causes some of the answers to stop making sense. – Gilles Jul 5 '11 at 22:48
  • noted on that @Gilles and thanks for the help. – afbr1201 Jul 7 '11 at 14:37

You're using the wrong quotes: single quotes '' prevent expansion of $ expressions ($var and $(command), and the legacy `command` form). Use double quotes "" instead. Although in this case, if you're certain that it's a number then you don't need any quotes.

For your second question... are you using leading zeroes? That indicates octal, so the digits 8 and 9 won't work.

  • yes, i am leading zeros, i need to grep a certain line with zeroes but the format of it was 01,02,03 so on so i need to grep like 03-04 but i think its not working. – afbr1201 Jul 5 '11 at 17:34
  • 1
    If you need to do that, you need to omit the leading zeroes for the math part and then use printf to reformat with the leading zero. Or you can try using 10#$number to see if it will force base 10. – geekosaur Jul 5 '11 at 17:40
  • Nice catch on the octal thing. The question needs to be restated if he's actually wanting to increment a string with a leading 0. – Mark Jul 5 '11 at 17:47
  • @mark, thanks for the suggestion, @geekosaur -- yes i am trying to grep something with leading zeroes,, and appending 10# did work, now i just have to do it the harder way.. haha, thanks guys! – afbr1201 Jul 5 '11 at 18:12

geekosaur has already explained why your first attempt failed. Here are some additional tips on what you're trying to do.

If you're looking for a number like 42, you probably want to match 042 but not 1042 or 421. All you need to achieve that is a fancier regular expression. Assuming $newnumber contains the number (integer, positive, in decimal notation) with no leading zero, look for $newnumber preceded by either the beginning of the line or a non-digit character, and likewise after. 0* further allows leading zeroes. The -E option tells grep that you're using the modern regular expression syntax (as opposed to the historical syntax, which is quirkier and less powerful).

grep -E "(^|[^0-9])0*$newnumber(\$|^[0-9])" /path/to/file

To parse a number with potential leading zeroes, in bash, you can use $((10#$newnumber)) to force a decimal interpretation. In other shells, it's a little more complicated; there's a shell construct to get the value of a variable without a particular prefix ${var#prefix}, and a similar construct for suffixes ${var%suffix}, but there's no way to specify “the longest possible sequence of 0 characters” as a prefix to strip. But it can be done in two steps: first obtain the part of var that isn't the leading zeroes, and use that as a prefix to strip. The part of var that isn't the leading zeros is its longest suffix that begins with a non-zero, which is ${var%%[!0]*} (the double % means to take out the longest suffix that matches the pattern; a single % would take out the shortest suffix).

read number

Further note: grep REGEXP /some/file searches the one file /some/file. If you want to search all the files in a directory, let the shell generate the list of files: grep REGEXP /some/dir/*. If you want to search all the files in a directory and its subdirectories recursively, pass the -r option to grep to make it recurse: grep -r REGEXP /some/dir.

  • this line worked fine number=${number#${number%%[!0]*}} the problem now it i want to force a 0 on the output as well to make it a 2 digit number, E.G. 01-09 but not 010-099. any suggestion? – afbr1201 Jul 7 '11 at 14:37
  • A simple solution is to use printf: printf %02d "$number", or printf '%02d\n' "$number" if you want to add a newline. – Gilles Jul 7 '11 at 15:43

As geekosaur said, you're using the wrong quotes. Stick with doublequotes when you want the shell to expand a variable reference to a value.

Secondly, you are doing the math inside the double parentheses wrong. You DON'T want a $ inside there, variable references inside the $(( )) construct don't need a $.

echo "enter number"
read number
newnumber=$((newnumber + 1))
echo "$number changes to $newnumber"

Those two changes work for me in your original too...

read var
newvar=$((newvar + 1))
printf -v newvar "%02d" "$newvar"
grep "$newvar" /some/dir

UPDATE added the printf line to format output. UPDATE 2 added in the fix for entering zero padded numbers. This should be a complete example now.

  • Assuming number contains a bunch of digits, $((number+1)) is exactly equivalent to $(($number)). Parameter substitution is performed within arithmetic expressions. – Gilles Jul 5 '11 at 20:17
  • It is still a bad habit to get into and shows a fundamental misunderstanding of the $((...)) construct. Let him try $(($number+=50,$number/2)) someday and see what he gets. – Mark Jul 6 '11 at 17:39
  • That's obviously broken (if $number contains digits): you don't write $foo=bar for an assignment in the shell. (But actually $(($x+=50)) can make sense, if $x is the name of another variable!) (Of course I meant $((number+1)) is equivalent to $(($number+1)) above.) – Gilles Jul 6 '11 at 18:15
  • hi i tried that line but it would give me an error token value is too great for base enter number 09 a: line 4: 09: value too great for base (error token is "09") – afbr1201 Jul 7 '11 at 14:28
  • Yeah, user774187, the octal thing that geekosaur pointed out is going to bite you when printf runs. You'd need printf -v newvar "%02d" "10#$newvar" to avoid that issue. – Mark Jul 7 '11 at 14:33

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.