grepping a variable and adding 1 to it
Solution 1
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.
Solution 2
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
number=${number#${number%%[!0]*}}
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
.
afbr1201
Updated on September 18, 2022Comments
-
afbr1201 almost 2 years
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:
#!/bin/bash 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:#!/bin/bash echo "enter number" read number 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?
-
Gilles 'SO- stop being evil' almost 13 years@user774187 Please don't edit away a whole chunk of your question, as it causes some of the answers to stop making sense.
-
afbr1201 almost 13 yearsnoted on that @Gilles and thanks for the help.
-
-
afbr1201 almost 13 yearsyes, 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.
-
geekosaur almost 13 yearsIf 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 using10#$number
to see if it will force base 10. -
Karu almost 13 yearsNice catch on the octal thing. The question needs to be restated if he's actually wanting to increment a string with a leading 0.
-
afbr1201 almost 13 years@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!
-
Gilles 'SO- stop being evil' almost 13 yearsAssuming
number
contains a bunch of digits,$((number+1))
is exactly equivalent to$(($number))
. Parameter substitution is performed within arithmetic expressions. -
Karu almost 13 yearsIt 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. -
Gilles 'SO- stop being evil' almost 13 yearsThat'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.) -
afbr1201 almost 13 yearshi 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")
-
Karu almost 13 yearsYeah, 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. -
afbr1201 almost 13 yearsthis 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 almost 13 yearssame thing happened @Mark, #!/bin/bash echo "enter number" read var newvar=$((var + 1)) printf -v newvar "%02d" "10#$newvar" output enter number 09 a: line 6: 09: value too great for base (error token is "09")
-
Gilles 'SO- stop being evil' almost 13 yearsA simple solution is to use
printf
:printf %02d "$number"
, orprintf '%02d\n' "$number"
if you want to add a newline. -
Karu almost 13 yearsI thought you only needed help with
printf
from me. Sorry. I'll edit my answer further. -
afbr1201 almost 13 yearsi wanted to try various ways, but that printf wont work for me yet.. and i really appreciate you guys helping me out,.. i am still a newbie on bash..
-
Admin about 2 years(1) The bit about “grep” is an incandescent red herring. The OP explicitly said that they want to grep for number and newnumber in
/some/dir
, but it wasn’t a critical part of the question. It’s OK that you didn’t bother regurgitating it, but to claim that your answer is somehow more streamlined than the others is just bragging about how you did half of the job using half as much time. (2) The trick with10000
does not work. (3) Even if it did, you should explain how it works.