1

My projects have files web/.htaccess

Somewhere inside, each has a line like

SetEnv BUILD_ID 1443.303.0001016

I typically update these numeric fields (within a cron script) with:

grep "^SetEnv BUILD_ID " .htaccess && sed -i.bak -r 's/^(SetEnv BUILD_ID )([0-9]+)\.([0-9]+)\.(0*)([0-9]+)(.*)/printf "\1"$(date +%y%U.%j.)"%05d"$((\5+1))\6/ge' .htaccess 

As you can see, the first two merely derive from the timestamp: yyWeekOfYear.DayOfYear.0001016

QUESTION The above sed correctly sets fields 1 and 2, but field 3 gets padded with five zeros, like so:

SetEnv BUILD_ID 1444.307.000001017

How can I increment this field 3 and update the whole line in-place in the file, using only modern awk/gawk , such that field 3 will have exactly 7 digits, padded by zeroes? Assume that none of my projects will ever have a minor version number that surpasses 10^7.

Or maybe this can be done using only date and bash ?

Similar in part to Perl / Awk / Sed - Find and Replace Number & auto-increment and Add leading zeroes to awk variable

Community
  • 1
  • 1
Marcos
  • 4,796
  • 5
  • 40
  • 64
  • 1
    So you just want to replace the line with exactly the same but +1 to the bit after the last dot ? How do you update week and day of year ? –  Nov 03 '14 at 13:10
  • awk cannot do inline replacement and not clear why `yyWeekOfYear.DayOfYear` won't get incremented – anubhava Nov 03 '14 at 13:30
  • 1
    @anubhava Newest Gawk has inline capabilities –  Nov 03 '14 at 13:42
  • Yes I have read about it but very few systems have it. – anubhava Nov 03 '14 at 13:44
  • @Jidder Fields 1 and 2 don't get autoincremented. Merely get re-evaluated, by `date` or hopefully some env vars already built into `bash` or `awk` to keep the code short. (That part was already working in the `sed` version) – Marcos Nov 03 '14 at 14:44

1 Answers1

2

This should do what you want, all in awk:

awk '/SetEnv BUILD_ID/{split($3,a,".")
              $3=sprintf("%s.%07d",strftime("%y%U.%j",systime()),+a[3]+1)}
     1' .htaccess >tmp && mv tmp .htaccess

One-liner:

awk '/SetEnv BUILD_ID/{split($3,a,".");$3=sprintf("%s.%07d",strftime("%y%U.%j",systime()),+a[3]+1)}1' .htaccess >tmp && mv tmp .htaccess
  • It splits field 3 by .
  • Then sets field 3 to formatted date and the 3rd field from the split command
  • 1 prints all lines.
  • Writes this into a tmp file.
  • If it succeeded then overwrites current file with the tmp.
  • Thanks. Except the last part; I am hoping to find some inline file editing like `-i.bak` in `sed` above. Nothing special in the man page for `awk` in Linux (Ubuntu 14.04). This will avoid shell confusion with my preexisting `grep ... && ...` filter, which is important to me. – Marcos Nov 03 '14 at 14:52
  • Using awk's new inplace edit, my final version is `tty -s && grep "^SetEnv BUILD_ID " web/.htaccess && awk -i inplace -v INPLACE_SUFFIX=.bak '/SetEnv/{split($3,a,".");$3=sprintf("%s.%07d",strftime("%y%U.%j",systime()),+a[3]+1)}1' web/.htaccess` The `tty -s` makes it update only when the script is run interactively, not from crontab. – Marcos Nov 03 '14 at 15:14
  • @Marcos Why are you grepping though ? The awk will take care of that for you, if it doesn't find that line nothing will change. Also i left -i out as it is a very new feature and most people won't have it. –  Nov 03 '14 at 15:54
  • grep prevented sed from touching the file (timestamp) even when no matching line was found. I don't know how new awk behaves in that situation (preserving unmatched file timestamp). – Marcos Nov 04 '14 at 10:29
  • Minor nitpick,seeing your newly edited version. Our .htaccess files may have many SetEnv lines for Apache webserver variables other than BUILD_ID. So your `/SetEnv/` early in the line may need to be more specific to avoid damaging irrelevant lines, i.e.: `/SetEnv BUILD_ID /` – Marcos Nov 04 '14 at 11:01
  • @Marcos If no matching line is found it does nothing at all. Also i have edited to include BUILD_ID –  Nov 04 '14 at 11:40