Chinaunix

标题: 需要按照自己的格式输出,应该如何做(有答案的同时有讲解更好),awk? [打印本页]

作者: lzolder    时间: 2010-05-26 11:39
标题: 需要按照自己的格式输出,应该如何做(有答案的同时有讲解更好),awk?
原始文件如:

  1. 物质1:
  2. 属性1:aaaa
  3. 属性2:bbb
  4. 属性3:ccc
  5. ...

  6. 物质2:
  7. 属性1:ddd
  8. 属性2:eee
  9. 属性3:fff
  10. ...

  11. ...
复制代码
想得到如下输出
  1. 属性1       属性2      属性3
  2. aaa        bbb         ccc
  3. ddd       eee         fff
复制代码
请高手帮忙,如果能提供讲解,那就更感谢了。
作者: where27    时间: 2010-05-26 12:20
回复 1# lzolder
  1. awk -F: 'BEGIN{print "属性1\t属性2\t属性3"}/属性[12]/{printf $2"\t"}/属性3/{print $2}' file
复制代码
BEGIN{...}打印表头,后面打印相应的内容,不过文本里属性1属性2属性3得是按顺序排下来的,不然就不灵了
作者: bbgg1983    时间: 2010-05-26 12:35
回复 2# where27


    有省略号啊,表头的属性不止有三个吧?直接打估计够呛
作者: renxiao2003    时间: 2010-05-26 12:52
是啊。这个数据有点难度。
作者: lzolder    时间: 2010-05-26 12:58
本帖最后由 lzolder 于 2010-05-26 13:04 编辑

首先谢谢老表的回复。bbgg1983说对了,我按照老表的思路没实现
我的原始文件如下

  1. Enclosure Device ID: 8
  2. Slot Number: 22
  3. Device Id: 31
  4. Sequence Number: 2
  5. Media Error Count: 0
  6. Other Error Count: 0
  7. Predictive Failure Count: 0
  8. Last Predictive Failure Event Seq Number: 0
  9. PD Type: SATA
  10. Raw Size: 931.512 GB [0x74706db0 Sectors]
  11. Non Coerced Size: 931.012 GB [0x74606db0 Sectors]
  12. Coerced Size: 930.390 GB [0x744c8000 Sectors]
  13. Firmware state: Online
  14. SAS Address(0): 0x500e004aaaaaaa16
  15. Connected Port Number: 4(path0)
  16. Inquiry Data:             9QJ3LCXTST31000340NS                            SN06   
  17. FDE Capable: Not Capable
  18. FDE Enable: Disable
  19. Secured: Unsecured
  20. Locked: Unlocked
  21. Foreign State: None
  22. Device Speed: 3.0Gb/s
  23. Link Speed: 3.0Gb/s
  24. Media Type: Hard Disk Device

  25. Enclosure Device ID: 8
  26. Slot Number: 23
  27. Device Id: 32
  28. Sequence Number: 4
  29. Media Error Count: 0
  30. Other Error Count: 0
  31. Predictive Failure Count: 0
  32. Last Predictive Failure Event Seq Number: 0
  33. PD Type: SATA
  34. Raw Size: 931.512 GB [0x74706db0 Sectors]
  35. Non Coerced Size: 931.012 GB [0x74606db0 Sectors]
  36. Coerced Size: 930.390 GB [0x744c8000 Sectors]
  37. Firmware state: Online
  38. SAS Address(0): 0x500e004aaaaaaa17
  39. Connected Port Number: 4(path0)
  40. Inquiry Data:             9QJ3EBPVST31000340NS                            SN06   
  41. FDE Capable: Not Capable
  42. FDE Enable: Disable
  43. Secured: Unsecured
  44. Locked: Unlocked
  45. Foreign State: None
  46. Device Speed: 3.0Gb/s
  47. Link Speed: 3.0Gb/s
  48. Media Type: Hard Disk Device
复制代码
我想要得到的结果是:

  1. Enclosure ID Slot Number   Device Id   Raw Size  Inquiry Data
  2. 8 22                 31              931.512 GB   9QJ3LCXTST31000340NS
  3. 8 23                 32              931.512 GB   9QJ3EBPVST31000340NS
复制代码
我的原始文件不只2个磁盘信息,还有很多个
而我想得到的结果,我不仅限于Enclosure Device ID、Slot Number、Device Id、Raw Size、Inquiry Data,比如我可能需要去掉Device id,然后增加Link Speed属性

不知我说清楚我的需求了没?
作者: ywlscpl    时间: 2010-05-26 13:08
  1. awk -F ':' '{if (/:$/) {m=0;n++}else if ($2) {a[n","$1]=$2;m++;b[n","m]=$1}}END{for (i=1;i<=m;i++) printf b[1","i]"\t";print "";for (i=1;i<=n;i++) {for (j=1;j<=m;j++) printf a[i","b[i","j]]"\t";print ""}}' file
复制代码

作者: ywlscpl    时间: 2010-05-26 13:10
写好了,发现数据已经变了
作者: ywlscpl    时间: 2010-05-26 13:32
全部属性
  1. awk -F '\n' -v RS=  '{for (i=1;i<=NF;i++) {split($i,m,":");a[NR","i]=m[1];b[NR","i]=m[2]}}END{for (i=1;i<=NF;i++) printf a[1","i]"\t";print "";for (i=1;i<=NR;i++) {for (j=1;j<=NF;j++) printf b[i","j]"\t";print ""}}' file
复制代码

作者: lzolder    时间: 2010-05-26 14:11
本帖最后由 lzolder 于 2010-05-26 14:14 编辑

按照老表的思路我如果这样写
  1. awk -F: 'BEGIN {print "Enclosure Device ID\tSlot Number\tDevice Id"}/Enclosure Device ID/{print $2}' file
复制代码
可以输出:
  1. Enclosure Device ID     Slot Number     Device Id
  2. 8
  3. 8
  4. 8
  5. 8
  6. 8
  7. 8
  8. 8
  9. 8
  10. 8
  11. 8
  12. 8
  13. 8
  14. 8
  15. 8
  16. 8
  17. 8
  18. 8
  19. 8
  20. 8
  21. 8
  22. 8
  23. 8
  24. 8
  25. 8
复制代码
但是我写
  1. awk -F: 'BEGIN {print "Enclosure Device ID\tSlot Number\tDevice Id"}/Enclosure Device ID/{print $2}/Slot Number/{print $2}' file
复制代码
结果就变成了:
  1. Enclosure Device ID     Slot Number     Device Id
  2. 8
  3. 0
  4. 8
  5. 1
  6. 8
  7. 2
  8. 8
  9. 3
  10. 8
  11. 4
  12. 8
  13. 5
  14. 8
  15. 6
  16. 8
  17. 7
  18. 8
  19. 8
  20. 8
  21. 9
  22. 8
  23. 10
  24. 8
  25. 11
  26. 8
  27. 12
  28. 8
  29. 13
  30. 8
  31. 14
  32. 8
  33. 15
  34. 8
  35. 16
  36. 8
  37. 17
  38. 8
  39. 18
  40. 8
  41. 19
  42. 8
  43. 20
  44. 8
  45. 21
  46. 8
  47. 22
  48. 8
  49. 23
复制代码
我应该如何实现0 1 2 3 4 ... 23出现在第二列呢?
作者: bbgg1983    时间: 2010-05-26 14:35
回复 8# ywlscpl


    awk在你手里真是无所不能丫
作者: Shell_HAT    时间: 2010-05-26 14:41
回复 9# lzolder
  1. awk -F: 'BEGIN {print "Enclosure Device ID\tSlot Number\tDevice Id"}/Enclosure Device ID|Slot Number/{printf $2"\t"}/Device Id/{print $2}' file
复制代码

作者: lzolder    时间: 2010-05-26 14:42
全部属性
ywlscpl 发表于 2010-05-26 13:32



    如果是部分属性呢?好好研究下你的脚本,头晕中
作者: ywlscpl    时间: 2010-05-26 14:45
想输出什么字段,在BEGIN里加
  1. awk -F '\n' -v RS=  'BEGIN{d["Enclosure ID"];d["Slot Number"];d["Device Id"];d["Raw Size"];d["Inquiry Data"]}{for (i=1;i<=NF;i++) {split($i,m,":");a[NR","i]=m[1];b[NR","i]=m[2]}}END{for (i=1;i<=NF;i++) if (a[1","i] in d) printf a[1","i]"\t";print "";for (i=1;i<=NR;i++) {for (j=1;j<=NF;j++) if (a[1","j] in d) printf b[i","j]"\t";print ""}}' file
复制代码

作者: where27    时间: 2010-05-26 14:45
回复 13# ywlscpl


    高手高手高高手
作者: lzolder    时间: 2010-05-26 15:00
  1. awk -F: 'BEGIN {print "Enclosure Device ID\tSlot Number\tDevice Id"}/Enclosure Device ID|Slot Number/{printf $2"\t"}/Device Id/{print $2}' file
复制代码
如果我增加一个属性,PD Type
是否应该写成
  1. awk -F: 'BEGIN {print "Enclosure Device ID\tSlot Number\tDevice Id"}/Enclosure Device ID|Slot Number|Device Id/{printf $2"\t"}/PD Type/{print $2}' file
复制代码

作者: Shell_HAT    时间: 2010-05-26 15:01
换个思路:
  1. awk -F: '/Enclosure Device ID|Slot Number|Device Id/{a[$1]=a[$1]":"$2}END{for(i in a)print i,a[i]}' urfile | awk -F: '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(i=1;i<=NF;i++){for(j=1;j<=NR;j++)printf ("%-20s",a[j,i]);print ""}}'
复制代码
想输出什么字段,在pattern里加
作者: lzolder    时间: 2010-05-26 15:35
  1. awk -F: 'BEGIN {print "Enclosure ID\tSlot\tDevice Id\t\tPD Type\t\t\tRaw Size\t\t\t\tstate"}/Enclosure Device ID|Slot Number|Device Id|PD Type|Raw Size/{printf $2"\t\t"}/Firmware state/{print $2}' file
复制代码
我用以上代码基本实现了我想要得到的输出
下来看看shell_hat 和ywlscpl两位高手的代码,实在是晕得厉害
作者: expert1    时间: 2010-05-26 22:23
本帖最后由 expert1 于 2010-05-27 12:42 编辑

很简单,行列互换可以说无非是换ORS,FS,RS,OFS这几个,看你玩的是否熟练罢了
  1. awk 'BEGIN{FS="[:\[]";print"Enclosure Device ID\tSlot Number\tDevce Id\tPD Type\tRaw Size"}
  2.     {                                                                        if(/Enclosure Device ID|Slot Number|Device Id|PD Type|Raw Size/)                                                                                  {ORS="\t"; print $2}                                           else if(/^$/)                                                                 {ORS="\n"; print "  "}                                             }'
复制代码
结果为:
  1. Enclosure Device ID     Slot Number     Devce Id        PD Type Raw Size
  2. 8       22      31      SATA    931.512 GB      
  3. 8       23      32      SATA    931.512 GB
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2