0

When applying

awk -F'[,/]' '{sub(/\/[0-9]+/, "/" ($2+3) ); print $0}'

to input

Statements and Functions/399,Black,notBold

why is the output

Statements and Functions/402,Black,notBold

instead of

Statements and Functions 402 Black notBold

?

  1. -F'[,/]' changes the field separator FS to be either , or /, for awk to read the input.

    OFS is by default a whitespace. So when print $0, aren't all the fields $1, ..., and $NF joined with separator OFS to create $0?

  2. Change

    awk -F'[,/]' '{sub(/\/[0-9]+/, "/" ($2+3) ); print $0}'
    

    to

    awk -F'[,/]' '{sub(/\/[0-9]+/, "/" ($2+3) ); $1=$1; print $0}'
    

    will output

    Statements and Functions 402 Black notBold
    

    for input

    Statements and Functions/399,Black,notBold
    

    Then what are all the other cases (besides assigning to a field) so that $0 will be reformatted with OFS?

  3. If a field must be changed so that $0 will be reformatted with OFS, then why when

    awk -F'[,/]' '{sub(/\/[0-9]+/, "/" ($2+3) ); print $0;  print $2;  print $0}'
    

    applies to input

    Statements and Functions/399,Black,notBold
    

    the output shows that the value of $2 changes, while $0 remains unaffected by OFS?

    Statements and Functions/402,Black,notBold
    402
    Statements and Functions/402,Black,notBold
    
1

You have to convince awk that the fields have changed to force it to reformat them with OFS. If you make a substitution on the whole $0 as in your case then awk doesn't see the need to split it into pieces and reformat back.

You can do something like this to make it accept that things have changed:

awk -F'[,/]' '{sub(/\/[0-9]+/, "/" ($2+3) ); $1=$1; print $0}'

The $1=$1 does the trick :)

Note that the sub() doesn't change $2 - it scans and changes $0 and updates it with the value of $2+3. But it doesn't update $2, it updates $0 hence it doesn't trigger reformatting.

  • Thanks. Do you mean that when OFS applies to $0 is when $0 is reformatted? Could you list all the cases when $0 is reformatted, besides the case when a field is assigned to? – Tim Jul 18 '17 at 3:37
  • Does sub(/\/[0-9]+/, "/" ($2+3) ) change the value of $2? If yes, why does it not cause $0 to be reformatted? If no, why is the value of $2 in the output of $0 increased by 3? – Tim Jul 18 '17 at 3:41
  • @Tim it's also used when printing out individual fields, e.g. awk -F'[,/]' 'print $1,$2,$3,$4}' – MLu Jul 18 '17 at 3:41
  • @Tim - nope, the sub() doesn't change $2. If scans $0 for /[0-9]+ and replaces that with the value of $2+3. But it doesn't modify $2, it modifies $0, hence it doesn't trigger reformatting. – MLu Jul 18 '17 at 3:43
  • Do you mean printing out individual fields will also cause $0 to be reformatted? If yes, the output of awk -F'[,/]' '{for (i=1; i <= NF; i++) print $i; print $0}' on Statements and Functions/402,Black,notBold is still Statements and Functions/402,Black,notBold instead of Statements and Functions 402 Black notBold. – Tim Jul 18 '17 at 3:45
1

I believe that you will be better served by using:

awk -F'[,/]' '{$2=($2+3)}1' infile

with infile as this:

$ cat infile
The Ubiquitous Backslash/49,Black
The Ubiquitous Backslash/17,Black
Statements and Functions/399,Black,notBold

You will get:

$  awk -F'[,/]' '{$2=($2+3)}1' infile
The Ubiquitous Backslash 52 Black
The Ubiquitous Backslash 20 Black
Statements and Functions 402 Black notBold

HTH

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.