使用Awk Statemnt格式化数据

时间:2017-03-09 10:11:12

标签: shell unix awk

我有像

这样的数据
name1 123
name1 324
name2 123
name2 324
name2 456

现在我想要O / P喜欢

name1 123
      324
name2 123
      324
      456

名称不应重复

4 个答案:

答案 0 :(得分:2)

<强>来源

name1 123
name1 324
name2 123
name2 324
name2 456

<强>代码

awk '{$1= a[$1]++ ? "" : $1}1' OFS="\t" file

<强>结果

name1    123
         324
name2    123
         324
         456

<强>解释

让我们使用ternary运算符。

如果是我们的键$1,则在数组a[$1]++中看到第一个字段,然后将第一个字段设置为空字符串"",否则将保留实际值。< / p>

最后的1只是一个快捷方式,以避免使用print语句。

在awk中条件匹配时,默认操作是打印输入行。

$ echo "test" |awk '1'

相当于:

echo "test"|awk '1==1'

echo "test"|awk '{if (1==1){print}}'

那是因为1将永远是真的

最后一步将de O utput F ield S eparator设置为TAB OFS="\t"以获得我们的预期结果。< / p>

答案 1 :(得分:0)

如果您的文件已排序,请尝试此

$ cat file
name1 123
name1 324
name2 123
name2 324
name2 456

对于已排序的文件

$ awk '$1!=p{print;p=$1;next}{printf("%*s %s\n",length(p)," ",$2)}' file
name1 123
      324
name2 123
      324
      456

对于未分类的文件

$ awk '{a[$1]=$1 in a ? sprintf("%s\n%*s %s",a[$1],length($1)," ",$2): $2}END{for(i in a)print i, a[i]}' file
name1 123
      324
name2 123
      324
      456

更好的可读版本

awk '
     {
       a[$1]=$1 in a ? sprintf("%s\n%*s %s",a[$1],length($1)," ",$2): $2
     }
  END{
       for(i in a)
           print i, a[i]
     }
    ' file

即使您的输入文件未按照下面的方式排序,上面的输入文件也会有效

$ cat unsorted file
name1 123
name2 123
name1 324
name2 324
name2 456

答案 2 :(得分:0)

@ Rbk528:试试:

awk '{printf("%s %s\n",!a[$1]++?$1:"     ",$2)}'   Input_file

答案 3 :(得分:0)

我知道您要求awk,但大多数地方awk还有perl

perl -lape 's/^(\w+)/" "x length($1)/e if $seen{$F[0]}++;'