2

猫错误00

4  0    375
4 2001   21
4 2002   20

猫错误01

4 0      465
4 2001   12
4 2002   40
4 2016   1

我想要输出如下

4 0      375   465
4 2001   21    12
4 2002   20    20
4 2016   -     1

我正在使用以下查询。这里的问题是我无法处理两个字段的 grep,因为空间即将到来。请建议如何摆脱这种情况。

keylist=$(awk '{print $1,$2'} Error0[0-1] | sort | uniq)
for key in ${keylist} ; do
echo ${key}
        val_a=$(grep "^${key}" Error00 | awk  '{print $3}') ;val_a=${val_a:---}
        val_b=$(grep "^${key}" Error01 | awk '{print $1,$2}') ; val_b=${val_b:---    --}
        echo $key  ${val_a} >>testreport
done

我得到如下输出

4       375   465
0
4       21    12
2001
4       20    20
2002
4       -     1
2016
4

2 回答 2

4

一个单一awk的班轮可以很容易地处理这个:

awk 'FNR==NR{a[$1,$2]=$3;next}{print $1,$2,(a[$1,$2]?a[$1,$2]:"-"),$3}' err0 err1
4 0 375 465
4 2001 21 12
4 2002 20 40
4 2016 - 1

对于格式化输出,您可以使用printf而不是print. 就像Jonathan Leffler建议的那样:

printf "%s %-6s %-6s %s\n",$1,$2,(a[$1,$2]?a[$1,$2]:"-"),$3
4 0      375    465
4 2001   21     12
4 2002   20     40
4 2016   -      1

然而,一个通用的解决方案是使用column -t一个漂亮的表格输出:

awk '{....}' err0 err1 | column -t
4  0     375  465
4  2001  21   12
4  2002  20   40
4  2016  -    1
于 2013-09-20T08:56:48.283 回答
1

grep并不是真正适合这项工作的工具。您可以使用awkPerl(或 Python,或……),也可以使用join. 但是,join一次只能连接一列,您似乎需要连接两列。因此,我们将不得不对数据进行按摩,以便它可以与join. 我将假设您正在使用bash,因此可以使用流程替换。你可以在没有的情况下完成这项工作,但它更复杂并且涉及临时文件(以及清理它们的陷阱等)。

连接的关键是用冒号(或任何其他方便的字符 - control-A 也可以)替换前两列之间的空白,然后用替换字符连接第 1 列上的文件。输入必须排序;输出必须将冒号替换为空白。

$ join -o 0,1.2,2.2 -a 1 -a 2 -e '-' \
>     <(sed 's/  */:/' Error00 | sort) \
>     <(sed 's/  */:/' Error01 | sort) |
> sed 's/:/ /'
4 0 375 465
4 2001 21 12
4 2002 20 40
4 2016 - 1
$

's/ */:/'操作将一个或多个空格的第一个序列替换为冒号;输入数据在第一行的 4 和 0 之间有两个空格Error00。输入join必须按照加入字段的排序顺序,这里是第一个字段。输出是连接字段,第二列Error00和第二列Error01(记住这意味着前两列被冒号融合后的第二列)。如果第一个文件中有不匹配的行,则生成输出行 ( -a 1);第二个文件同上;对于缺少的字段,插入破折号 ( -e '-')。最后sed删除添加的冒号。

如果要格式化数据,请通过awk.

$ join -o 0,1.2,2.2 -a 1 -a 2 -e '-' \
>     <(sed 's/  */:/' Error00 | sort) \
>     <(sed 's/  */:/' Error01 | sort) |
> sed 's/:/ /' |
> awk '{printf("%s %-6s %-6s %s\n", $1, $2, $3, $4)}'
4 0      375    465
4 2001   21     12
4 2002   20     40
4 2016   -      1
$
于 2013-09-20T06:53:49.137 回答