0

I have found a partial solution to my issue in: "Changing the case of a string with awk", the command posted by @AndersJohansson is:

echo 'ABCD EFGH IJKL MNOP QRST UVWX' | awk '{for (i=1; i<=NF; ++i) { $i=toupper(substr($i,1,1)) tolower(substr($i,2)); } print }'

Which ends printing Abcd Efgh Ijkl Mnop Qrst Uvwx, as expected. But, in my case I have the data separated by fields, like: ABCD EFGH; IJKL MNOP; QRST UVWX and I need to apply the command to the 3r (last) field only (actually in my data there are 9 fields, but for simplicity I put just 3).

Expected output: ABCD EFGH; IJKL MNOP; Qrst Uvwx

Inside Stackoverflow there is a good number of related questions, even one of my own (How to sort inside a cell captured by awk) , I went one by one trying to adapt them to my case without success, obviously I have not enough knowledge about awk as to overcome with the solution, so I will really appreciate any help on solving this... thanks.

Andrés Chandía
  • 999
  • 1
  • 16
  • 32

1 Answers1

2

Maybe something like this:

echo "ABCD EFGH; IJKL MNOP; QRST UVWX" |
awk '
    BEGIN { FS = OFS = "; "}
    {
        s = "";
        n = split($NF,w,/ /);
        for(i=1; i<=n; ++i)
            s = s " " toupper(substr(w[i],1,1)) tolower(substr(w[i],2))
    }
    {$NF = substr(s,2)}
    1
'

output:

ABCD EFGH; IJKL MNOP; Qrst Uvwx
Explanations:
  • setting FS to ": " will make awk split the line in fields separated by ": "; in the current case, you'll get three fields.

  • $NF references the last field, which is then manually split on each space character.

  • The for loop does the upper/lower transformations and store them in a string variable.

  • Then the last field is updated and the whole line is printed; OFS has to be set to the same value as FS, or else the "; " will be converted to " " when printing the line.

Fravadona
  • 13,917
  • 1
  • 23
  • 35