[bash] Use Awk to extract substring

I am asking in general, how to write a compatible awk script that performs the same functionality ...

To solve the problem in your quesiton is easy. (check others' answer).

If you want to write an awk script, which portable to any awk implementations and versions (gawk/nawk/mawk...) it is really hard, even if with --posix (gawk)

for example:

  • some awk works on string in terms of characters, some with bytes
  • some supports \x escape, some not
  • FS interpreter works differently
  • keywords/reserved words abbreviation restriction
  • some operator restriction e.g. **
  • even same awk impl. (gawk for example), the version 4.0 and 3.x have difference too.
  • the implementation of certain functions are also different. (your problem is one example, see below)

well all the points above are just spoken in general. Back to your problem, you problem is only related to fundamental feature of awk. awk '{print $x}' the line like that will work all awks.

There are two reasons why your awk line behaves differently on gawk and mawk:

  • your used substr() function wrongly. this is the main cause. you have substr($0, 0, RSTART - 1) the 0 should be 1, no matter which awk do you use. awk array, string idx etc are 1-based.

  • gawk and mawk implemented substr() differently.