0

Using Linux bash.

I have the following code in a file and I want to change the numeric value (1000) to whatever other value.

file:

//...
if (counter==(1000)) {
// ...

I have tried to use this command:

sed 's/[0-9][0-9]+/9999/g' file.cpp

but nothing changes.

Moreover, I want the change to be permanent. How do I do this?

3
  • There is no such thing as "permanent" :-) You mean "persistent". Do you know that the number you want to change is exactly 1000, or that it's in parentheses, or that it occurs after count==(? I'm asking because you probably don't want to change every number in the code, right?
    – Kusalananda
    Commented Mar 12, 2021 at 8:34
  • The number is not always 1000. And yes. It will occur in the count==(. Yes the idea is to eventually make a bash script where I will substitute the number with a variable "grep"ed from a another file. Commented Mar 12, 2021 at 9:29
  • 3
    A little lateral thinking. "Magic" numbers in code are not helpful. Whatever language that code is, it will have variables. It would be much easier if that value was declared somewhere like MaxCount=1000;, because that would be much easier to identify with an edit, as relating to that specific instance of a number. Later, you might also consider making the value an external argument to the code. Commented Mar 12, 2021 at 9:44

1 Answer 1

3

You are using the + quantifier from the Extended Regular Expression Syntax set, but sed by default uses Basic Regular Expressions. So, you need to turn on ERE by adding the -E flag:

sed -E 's/[0-9][0-9]+/9999/' file.cpp

or use the corresponding BRE construct

sed 's/[0-9]\{2,\}/9999/' file.cpp

which is more portable (as noted by @Stéphane Chazelas).


Note that this will modify any line that contains two or more consecutive digits by replacing that group with 9999. If you want to ensure that only lines that conform to your example

if (counter==(1000)) {

are affected, I would recommend adding a suitable address specifier to make the matching more specific:

sed '/if (counter==([0-9]\{2,\}))/s/[0-9]\{2,\}/9999/' file.cpp 

That way, the substitution would only be performed on lines that match if (counter==(two-or-more-digit-number)).

The g option doesn't seem necessary because in your input example, there is only one such digit group on the line.


In order to modify the file directly, most sed implementations now understand the -i flag for "in-place" modifications. Again, as correctly noted by @Stéphane Chazelas, if you use it in combination with other flags, be sure to make the ordering right, as -i expects a suffix for creating a backup file (which may be left empty on GNU sed, but is required in FreeBSD/MacOS implementations):

  • sed -i '' -E 's/.../.../' will work on FreeBSD sed
  • sed -i -E 's/.../.../' or sed -Ei 's/.../.../' will work on GNU sed
  • sed -iE 's/.../.../' will not work as the E would be considered the backup suffix.
5
  • @StéphaneChazelas Btw, do we have a "canonical" answer dealing with the "locale-dependend collation order" problem of regular expressions that we can link to in cases like these?
    – AdminBee
    Commented Mar 12, 2021 at 9:51
  • There's Difference between [0-9], [[:digit:]] and \d but one could write a book about that issue as the behaviour varies greatly between tool, OS, libc, other lib and version of all the above. bash globs alone could have a whole chapter in that book. In practice [0123456789] is the only thing that is guaranteed to match only on those 10 digits characters (though in some locales could also match on parts of characters that include bytes 0x30..0x39 in their encoding). Commented Mar 12, 2021 at 10:23
  • Note that while GNU and FreeBSD added their -i independently around the same time, other BSDs added -i much later and went for the GNU approach. Commented Mar 12, 2021 at 11:40
  • Thanks a lot. your answer is much appreciated. Commented Mar 15, 2021 at 7:29
  • @GoldenRetriever You're welcome :)
    – AdminBee
    Commented Mar 15, 2021 at 9:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .