Find and substitute if greater than.

I have large config-files for an application. The lines have different structure, but some of them contains the parameter 'TIMEOUT=x', where x is an numeric value. I want to change the value for that specific paramater if the value is greater than a specific value (got that?). The timeout-parameter can be at different positions on different lines.

Example:

The file could look something like this:

# comment
KEYWORD=value KEYWORD="textstring"
KEYWORD        value,value,value TIMEOUT=400
KEYWORD=value KEYWORD=value TIMEOUT=200 KEYWORD=value
# Another comment
KEYWORD=value TIMEOUT=100

And I want to change the TIMEOUT-value to 200 if the value is greater than 200. The result should look like this:

# comment
KEYWORD=value KEYWORD="textstring"
KEYWORD        value,value,value TIMEOUT=200
KEYWORD=value KEYWORD=value TIMEOUT=200 KEYWORD=value
# Another comment
KEYWORD=value TIMEOUT=100

I know I can do this in a for-loop over all lines in the file, grep'ing and awk'ing out the value, echo'ing a new line in an if-else based on the value. The problem is that there are about 100 files with around 10000 lines each and it will take too long time to run a shell-loop.

Does anyone have any intelligent solution for this in awk or similar?

May be this?

$ awk -F= '/TIMEOUT=[0-9]+$/ && $NF > 200 {$NF=300}1' OFS== file
# comment
KEYWORD=value KEYWORD="textstring"
KEYWORD        value,value,value TIMEOUT=300
KEYWORD=value KEYWORD=value TIMEOUT=200 KEYWORD=value
# Another comment
KEYWORD=value TIMEOUT=100

Note: Pattern matching is purely based on the sample provided.

awk '{for(i = 1; i <= NF; i++)
  {if($i ~ /^TIMEOUT=[0-9]*$/)
    {gsub(/[^0-9]/, X, $i)
    if($i > 200)
      $i = "TIMEOUT=200"
    else
      $i = ("TIMEOUT=" $i)}}}1' file

perl solution

perl -lane 'for(@F)
  {if($_ =~ /^TIMEOUT=[0-9]*$/)
    {s/TIMEOUT=//;
    if($_ > 200)
      {$_ = "TIMEOUT=200"}
    else
      {$_ = "TIMEOUT=" . $_}}} print "@F"' file

Try also

awk     'match ($0, /TIMEOUT=[0-9]+/) &&
           substr($0, RSTART+8, RLENGTH-8) > 200        {$0=substr($0,1,RSTART+7) "200" substr($0, RSTART+RLENGTH) }
         1
        ' file