I have the following data structure in my test file:


I want to transform the third field so there is a '-' after the 3rd [A-Z] like so:


Is using the split() function the best tool for this job? Here is what I've attempted:

awk 'BEGIN{OFS=FS=","} {split($3, a, "[A-Z]{3}", seps); print seps[1]"/"seps[2]};' test

The above command does what I want, but how can I print the whole row including my updated $3 field? Result:


Short awk solution:

awk 'BEGIN{ OFS=FS="," }{ sub(/[A-Z]{3}/, "&-", $3) }1' file
  • [A-Z]{3} - regex pattern to match 3 uppercase letters
  • & - stands for the precise substring that was matched by the regexp pattern

The output:

  • If you cannot use {3}, you can always to it longhand with [A-Z][A-Z][A-Z]. – DopeGhoti Mar 1 '18 at 18:52

In awk, when you reassign the value of a field variable, the value of $0 is recalculated:

$ echo "A B C" | awk '{ $2 = "two"; print $0 }'
A two C

So in your case:

awk 'BEGIN{OFS=FS=","} {split($3, a, "[A-Z]{3}", seps); $3 = seps[1]"-"seps[2]; print $0}' test

Your description of the desired logic isn't 100% clear, but the following Sed command works on your example input:

sed 's/[A-Z]/&-/3' test-file.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.