1

为了检索文件第 13 列的所有租船人的 ascii 代码,我编写了这个脚本

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

但它不能以正确的方式工作!我的意思是它可以正常工作一段时间然后产生奇怪的结果!?例如,对于这个输入(假设它是第 13 列)

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

我必须得到这个

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

但我有这个

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

如您所见,第一个错误计算出现在字符“0”之后(结果为 48)。

你知道我的代码的哪一部分是造成这个错误的原因吗?!

4

2 回答 2

2

尝试这个:

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

\42is"\47is ',因此它printf %d "'${char}"在 shell 中为 each运行${char},这会触发作为 C 常量的评估,其 POSIX 扩展名指示数值,如POSIX printf 定义的 §Extended Description的最后一个项目符号中所述。

注意格式很重要!除非您确切知道自己在做什么,否则不要试图压缩代码!

还有一个纯awk解决方案(我直接从手册中获取了ord/chr函数):

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)
    }'
于 2012-04-24T10:27:41.203 回答
0

这可能对您有用:

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)}'
于 2012-04-24T11:56:10.023 回答