【问题标题】:bash -- merging and manipulation 2 filesbash -- 合并和操作 2 个文件
【发布时间】:2014-08-11 08:53:38
【问题描述】:

我有 2 个文件,我目前在 awk 中处理每个文件:

========================文件1:===================

 0x0002 RUNNING  EXISTS foo 253 65535
 0x0003 RUNNING  EXISTS foo 252 5
 0x0004 RUNNING  EXISTS foo 251 3

我对第一个字段和最后两个字段感兴趣。

字段 1:vdisk(十六进制)。最后两个字段是每个虚拟磁盘可能的 Cdisk。至少 1 必须存在。值是十进制的。 如果出现数字“65535”,则表示第二个cdisk不存在。

我使用这个 awk 来显示一个用户友好的表格:

 awk 'BEGIN {print "vdisk cdisk  Mr_cdisk"} 
 {
      if ( $3 ~ /EXISTS|THIS_AGENT_ONLINE/ ) {
           sub("65535", "N/A")
           printf "%-11s %-6s %s\n",$1,$(NF-1),$(NF)
      }
  }' ${FILE}

将生成此表:

vdisk  cdisk  Mr_cdisk
0x0002 253    N/A
0x0003 252    5
0x0004 1      3

======================== 文件2:===================

0x0000 Cmp cli Foo 0 SOME 0 0x0 0x0 0x0
0x0001 Cmp own Foo 1 NONE 0 0x0 0x0 0x0
0x0002 Cmp cli Foo 0 SOME 0 0x0 0x1 0x0
0x0003 Cmp own Foo 0 NONE 0 0x0 0x0 0x1
0x0004 Cmp cli Foo 0 SOME 0 0x0 0x0 0x0
0x0005 Cmp own Foo 1 NONE 0 0x1 0x0 0x0

我对“Cmp own”行感兴趣,其中第一个字段是 Cdisk(十六进制)。从末尾算起的第 5 个字段(就在 SOME/NONE 文本之前)是实例编号。它是 0 或 1。 我使用这个 awk 来显示一个用户友好的表格:

awk 'BEGIN {print "cdisk(hex)  RACE_Instance"}
                    /Cmp own/ {
                         printf "%-11s %-10s\n",$1,$(NF-5)
                    }' ${FILE};

这将产生下表:

cdisk(hex)  Instance
0x0001      1
0x0003      0
0x0005      1

++++++++++++++++++++++++++++++++++++++++++

我希望显示什么合并表。最好直接来自原始文件。 它应该将第一个数据分成 2 行(如果有超过 1 个 cdisk)。这将是合并的基础。然后打印实例编号(如果此 cdisk 存在)。

vdisk(hex)  cdisk(hex)  Instance
0x0002      0x00fd      N/A
0x0003      0x00fc      N/A
0x0003      0x0005      1
0x0004      0x0001      0
0x0004      0x0003      1

我肯定更喜欢 awk 的解决方案。 :)

谢谢!

编辑:向一个数据表添加更多信息和更正。

EDIT2:简化输入

【问题讨论】:

  • 那么您要合并哪个字段?您是否仍需要单独的表,或者您是否正在寻找一种直接从输入文件到最终输出的方法?
  • 我更愿意直接获得最终输出。我需要合并 cdisk 字段。每个“vdisk”最多可以有 2 个“cdisk”。 cdisk 或/和“Mr_cdisk”字段。
  • 我认为只要稍加努力,您就可以让我们更容易理解您的问题,从而帮助我们为您提供帮助。去掉 --non-decimal 数据标志,将您的示例输入输出减少到 3 或 4 行,每行 3 或 4 个空格分隔的字段,每个字段代表您当前的问题。
  • 添加了更多信息。希望这使它更清楚一点。非十进制标志使其“理解”输入(两个文件中的第一个字段)为十六进制,从而更容易转换为十进制。
  • 我知道非十进制标志的作用,我的意思是这只是混淆了你的问题。回答这个问题我们不需要知道任何事情。您需要在真实数据中处理这一事实并不会阻止您发布数据的简化版本,该版本不太复杂,因此突出了您的实际问题,当前问题是什么,因此使我们更容易为您提供帮助。如果你按照我的建议去做,那么你现在肯定会有答案了。

标签: bash awk filemerge


【解决方案1】:

我无法弄清楚从您的 2 个输入文件到输出的映射是什么,但这应该为您指明正确的方向:

$ cat tst.awk
NR==FNR {
    v2c[$1] = sprintf("0x%04x",$5)
    v2m[$1] = ( $6==65535 ? "N/A" : sprintf("0x%04x",$6) )
    next
}

$1 in v2c {
    print $1, v2c[$1], $5
    print $1, v2m[$1], $5
}
$
$ awk -f tst.awk file1 file2
0x0002 0x00fd 0
0x0002 N/A 0
0x0003 0x00fc 0
0x0003 0x0005 0
0x0004 0x00fb 0
0x0004 0x0003 0

【讨论】:

  • 我不确定要详细说明什么,它只是在读取第一个文件时填充几个关联数组,然后在读取第二个文件时将它们与第二个文件中的字段一起打印。有什么特别不明白的地方吗?
  • 好吧,我不太了解 awk 中的数组用法。每个文件如何分成每个数组?此外,结果与我的示例和预期表有点不同。 vdisk 0x2 仅与 cdisk 0xfd 相关联(第二个是 N/A),因此结果中应该只有一行。对于 vdisk 0x3、cdisk 0x5 和 vdisk 0x4 cdisk 0x3 都应该有实例 1。另外,vdisk 0x2、cdisk 0xfd 不应该有 0 作为实例。应为 N/A。如果我无法准确定义我需要什么,我很抱歉。感谢您的帮助。
  • 每个文件一次自动读取一行并拆分为字段(默认由空格分隔) 1->NF 所以当你看到 arr[$1] = $2 它填充一个数组 arr 由索引输入文件中的第一个字段值并包含第二个字段值。我知道输出不是您想要的我只是无法弄清楚您如何将文件内容映射到该输出,所以我给了您所需的结构,您可以整理映射。
  • 那么每个数组都在存储每个文件?
  • @Maxim_united - 另外,尝试将打印语句添加到脚本中以转储数组索引和值以及您不确定的任何其他内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-12
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多