1

To retrieve the ascii code of all charterers of column 13th of a file I write this script

awk -v ch="'" '{
for (i=1;i<=length(substr($13,6,length($13)));i++)
{cmd = printf \"%d\\n\" \"" ch substr(substr($13,6,length($13)),i,1) "\"" cmd | getline output close(cmd) ;
Number= Number " " output 
}
 print Number ; Number="" 
}' ~/a.test

but it doesn't work in the right way! I mean it works fine a while then produces the weird results!? As an example , for this input (assume it's column 13th)

CQ:Z:%8%%%%0%%%%9%%%%:%%%%%%%%%%%%%%%%%%

I have to get this

37 56 37 37 37 37 48 37 37 37 37 57 37 37 37 37 58 37 37 37 37 ...............

But I have this

37 56 37 37 37 37 48 48 48 48 48 57 57 57 57 57 58 58 58 58 58 ...............

As you can see first miss-computation appear after character "0" (48 in result).

Do you know which part of my code is responsible for this error ?!

2 Answers 2

2

Try this:

awk '{
    str = substr($13, 6)
    for (i=1; i<=length(str); i++) {
      cmd = "printf %d \42\47" substr(str, i, 1) "\42"    
      cmd | getline output
      close(cmd)
      Number= Number " " output 
    }
   print Number 
   Number="" 
  }' ~/a.test

\42 is " and \47 is ', so this runs printf %d "'${char}" in the shell for each ${char}, which triggers evaluation as a C constant with the POSIX extension dictating a numeric value as noted in the final bullet of the POSIX printf definition's §Extended Description.

N.B. The formatting matters! Don't try to squeeze the code unless you know exactly what you're doing!

And a pure awk solution (I took the ord/chr functions directly from the manual):

printf '%s\n' 'CQ:Z:%8%%%%0%%%%9%%%%:%%%%%%%%%%%%%%%%%%'|
  awk 'BEGIN { _ord_init() }
    {
      str = substr($0, 6)
      for (i = 0; ++i <= length(str);)
        printf "%s", (ord(substr(str, i, 1)) (i < length(str) ? OFS : ORS))
      }
    func _ord_init(    low, high, i, t) {
      low = sprintf("%c", 7) # BEL is ascii 7
      if (low == "\a") {     # regular ascii
        low = 0
        high = 127
       } 
      else if (sprintf("%c", 128 + 7) == "\a") {
        # ascii, mark parity
        low = 128
        high = 255
        } 
      else {                  # ebcdic(!)
        low = 0
        high = 255
       }

    for (i = low; i <= high; i++) { 
      t = sprintf("%c", i)
      _ord_[t] = i
       }
    }

  func ord(str,    c) {
    # only first character is of interest
    c = substr(str, 1, 1)
    return _ord_[c]
    }

  func chr(c) {
    # force c to be numeric by adding 0
    return sprintf("%c", c + 0)
    }'
Sign up to request clarification or add additional context in comments.

1 Comment

It's too bad that AWK (and gawk) don't have this POSIX printf(1) feature (see near the end of EXTENDED DESCRIPTION) in its builtin printf.
0

This might work for you:

awk -vSQ="'" -vDQ='"' '{args=space="";n=split($13,a,"");for(i=1;i<=n;i++){args=args space DQ SQ a[i] DQ;format=format space "%d";space=" "};format=DQ format "\\n" DQ;system("printf " format " " args)}'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.