awk - 根据另一个字段添加字段中的值

时间:2017-06-27 10:18:16

标签: bash awk

问题是不完整的,因为我无法找到一种表达它的好方法。我有这些数据:

Location   Group   Device#
--------------------------
location1  group01  10
location2  group10   8
location2  groupxx   7
location3  groupAA  11

期望的输出:

Location   Group   Device#   Total_Device#
------------------------------------------
location1  group01  10       10
location2  group10   8       15
location2  groupxx   7       15
location3  groupAA  11       11

我已经阅读了一些关于如何根据每个唯一Location进行求和的解决方案,但我希望将结果显示为“重复”,因为一个位置可以包含2个或更多个组,并且我想要显示每个小组也是如此。

3 个答案:

答案 0 :(得分:3)

<强>输入

$ cat infile
Location   Group   Device#
--------------------------
location1  group01  10
location2  group10   8
location2  groupxx   7
location3  groupAA  11

输出阅读文件

$ awk  'NR==1{print $0,"Total_Device#"}NR==2{print $0"--"}NR>2{a[$1]+=$NF; b[i++] = $0}END{for(i in b){split(b[i],d);print b[i],a[d[1]]}}' infile
Location   Group   Device# Total_Device#
----------------------------
location1  group01  10 10
location2  group10   8 15
location2  groupxx   7 15
location3  groupAA  11 11

<强>解释

awk  '                                        # call awk
      NR==1{                                  # when awk reads first record
           print $0,"Total_Device#"           # print current record/row with extra field
      }
      NR==2{                                  # when awk reads second record
           print $0"--"                       # print current record with extra string
      }
      NR>2{                                   # if no of records greater than 2 
            a[$1]+=$NF;                       # sum up last field based on location where array is a
            b[i++] = $0                       # save row in array b 
      }
      END{
            for(i in b){                      # loop through array b
                 split(b[i],d);               # split array value where separator being field separator
                 print b[i],a[d[1]]           # print row and location sum
            }
      }' infile

输出通过两次读取同一文件

$ awk  'FNR==NR{if(NR>2){loc[$1]+=$NF};next}FNR==1{print $0,"Total_Device#";next}{print $0,loc[$1]}' infile infile
Location   Group   Device# Total_Device#
-------------------------- 
location1  group01  10 10
location2  group10   8 15
location2  groupxx   7 15
location3  groupAA  11 11

<强>解释

awk  '                                        # call awk
      FNR==NR{                                # this is true when awk reads first file
              if(NR>2){                       # if no of records is greater than 2
                 loc[$1]+=$NF                 # sum up last field based on 1st field
              }
              next                            # go to next record, because of this keyword rest of the code will be skipped
      } 
                                              # here we read same file second time
      FNR==1{                                 # if no of records corresponding to current file is equal to one
              print $0,"Total_Device#";       # print current record/row and extra field
              next                            # go to next line
      }
      { 
              print $0,loc[$1];               # print current record and sum which is available in array loc

      }
   ' infile infile

答案 1 :(得分:2)

假设以制表符分隔的列。

档案 tot.awk

BEGIN{
   # set output separator
   OFS="\t"
}
NR==1{
   # print extended header
   print $0, "Total_Device#"
}
NR==2{
   # print header separator
   print
}
NR>2{
   # store original data in array
   loc[NR]=$1;
   grp[NR]=$2;
   cnt[NR]=$3;
   # store totals in associative array by location
   tot[$1]+=$3
}
END{
   # print each original line with calculated totals
   for (i=3; i<=NR; i++){
      print loc[i], grp[i], cnt[i], tot[loc[i]]
   }
}

输出:

> awk -f tot.awk data.txt
Location        Group   Device# Total_Device#
--------------------------
location1       group01 10      10
location2       group10 8       15
location2       groupxx 7       15
location3       groupAA 11      11

答案 2 :(得分:1)

一个可能性:

$lineCount = 0;
while (($line = fgetcsv($f)) !== false) {
    if ($lineCount > 1) {
        echo "<tr class='departmenttext'>";
        foreach ($line as $key => $cell) {
            if ($key == 1) {
               $cell = substr($cell, -3);
               echo '';
            }
            echo "<td>" . htmlspecialchars($cell) . "</td>";

            if ($key == 1) {
                echo "</tr>\n";
            }
        }
        echo "</tr>\n";
    }
    $lineCount = $lineCount + 1;
}

<强>结果

awk 'NR==FNR{if(/^location/){a[$1]+=$NF}next}{print $0, a[$1]}' your_file your_file

PD :我会留下标题修复。