简体   繁体   English

bash - 用零填充十六进制数字的awk

[英]bash - awk padding a hex number with zeroes

Input: 输入:

[0x000] : {foo   ,bar    ,0x0000000000a00000  ,abcd             ,143     ,65535   }
[0x001] : {foo   ,blah   ,0x0000000001e00000  ,abcd             ,142     ,65535   }
[0x002] : {foo   ,bar    ,0x0000000003000000  ,abcd             ,141     ,155     }
[0x003] : {foo   ,bar    ,0x0000000003000000  ,abcd             ,144     ,156     }

Desired output: 期望的输出:

0x0000 N/A 143
0x0002 155 141
0x0003 156 144

Currently using: sed -e 's/65535/N\\/A/g' -e 's/[][},]//g' | awk '/foo/ {print $1,$NF,$(NF-1)}' 目前正在使用: sed -e 's/65535/N\\/A/g' -e 's/[][},]//g' | awk '/foo/ {print $1,$NF,$(NF-1)}' sed -e 's/65535/N\\/A/g' -e 's/[][},]//g' | awk '/foo/ {print $1,$NF,$(NF-1)}'

I'd like to pad the first field to a 4 char hex number? 我想将第一个字段填充到4个字符的十六进制数字? How should I do it? 我该怎么办?

The input itself can already be a 4 char hex. 输入本身可以是4个字符的十六进制。 In that case it should leave it as is. 在这种情况下,它应该保持原样。

Also, is there a way to merge the sed and the awk into a single command? 还有,有没有办法将sed和awk合并为一个命令?

Thanks! 谢谢!

This awk line should do it alone: 这个awk系列应该单独完成:

awk 'BEGIN{FS="[ \t,:{}\\[\\]x]+"} $10==65535{$10="N/A"} {printf "0x%.4x %s %s\n", $3, $10, $9}'

Works with mawk and gawk . mawkgawk

Explanation: 说明:

  • BEGIN{FS=...} : sets the field separator to <space> , <tab> , , , [ , ] , : , { , } and x . BEGIN{FS=...}设置字段分隔符<space><tab>, []:{}x
  • $10==65535{$8="N/A"} If the 10th variable equals to 65535 is is set to N/A $10==65535{$8="N/A"}如果第10个变量等于65535,则设置为N/A
  • printf ... print the needed values in the desired output printf ...在所需的输出中打印所需的值

您可以使用mawk ,我刚刚修改了您的脚本,但是您可以使用awk (在本例中为mawk )本身完成所有这些操作:

(sed -e 's/65535/N\/A/g' -e 's/[][},]//g' | mawk '/foo/ {printf ("0x%04x %s %s\n", $1,$NF,$(NF-1))}') < File

Here is another awk 这是另一个awk

awk -F, '$6+0=="65535" {split($1,a,"[][]");$0=(length(a[2])==6?a[2]:"0x0"substr(a[2],3,4)) " N/A " $5}1' file
0x0000 N/A 143
0x2001 N/A 142
0x0002 N/A 141

If line contains 65535 change it, if not just print it. 如果行包含65535更改它,如果不是只打印它。
Test if length of hex is 6 character, if yes, just use it. 测试十六进制的长度是否为6字符,如果是,则使用它。
If not, pad an extra 0 to it. 如果没有,请为它填一个额外的0

Example data: 示例数据:

cat file
[0x000] : {foo   ,bar    ,0x0000000000a00000  ,abcd             ,143     ,65535   }
[0x2001] : {foo   ,bar    ,0x0000000001e00000  ,abcd             ,142     ,65535   }
[0x002] : {foo   ,bar    ,0x0000000003000000  ,abcd             ,141     ,65535   }
This line should not be modified
[0x002] : {foo   ,bar    ,0x0000000003000000  ,abcd             ,141     ,65533   }

awk -F, '$6+0=="65535" {split($1,a,"[][]");$0=(length(a[2])==6?a[2]:"0x0"substr(a[2],3,4)) " N/A " $5}1' file
0x0000 N/A 143
0x2001 N/A 142
0x0002 N/A 141
This line should not be modified
[0x002] : {foo   ,bar    ,0x0000000003000000  ,abcd             ,141     ,65533   }
 sed 's#\[0x\([[:xdigit:]]*\)].*,\([0-9]\{1,\}\)[[:space:]]*,[^,]*#0x0\1 N/A \2#;s/0x0\([[:xdigit:]]\{4\}\)/0x\1/' YourFile
  • take 2 group, first the hexa at start and the last before last , (using sed pattern behavior) and reformat with content of the 2 group 取2组,首先是开始时的hexa,最后是最后一个, (使用sed模式行为)并重新格式化2组的内容
  • could be shorter using 可以缩短使用时间 instead of [[:space:]] if space char are used instead of tab, and use of [0-9a-f] instead of [[:xdigit:]] 而不是[[:space:]]如果使用空格字符而不是制表符,则使用[0-9a-f]代替[[:xdigit:]]
  • added the 4 hexa correction (thanks @jotne) 添加了4个六角校正(谢谢@jotne)

Posix version so --posix for GNU sed Posix版本所以--posix用于GNU sed

If you are Ok with perl use this below command: 如果你使用perl,请使用以下命令:

perl -lane '$F[6]=~s/,/N\/A /g;
            if($F[7]=~/65535/){printf "0x%04s $F[6]\n", $1 if(/^\[0x([^\]]*)\]/)}
            else{print}' your_file

You can use printf : 你可以使用printf

printf "0x%.4x %s %s\n" $(sed -e 's/65535/N\/A/g' -e 's/[][},]//g' input  | awk '/foo/ {print $1,$NF,$(NF-1)}')
0x0000 N/A 143
0x0001 N/A 142
0x0002 N/A 141

Note: I am reusing your previous work here, only sent its output to printf 注意:我在此重复使用您之前的工作,只将其输出发送到printf

With GNU awk for handling non-decimal input data: 使用GNU awk处理非十进制输入数据:

$ awk --non-decimal-data -F'[][ ,]+' '/foo/{printf "0x%04x %s %s\n", $2, ($9==65535?"N/A":$9), $8}' file
0x0000 N/A 143
0x0001 N/A 142
0x0002 N/A 141

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM