【问题标题】:Awk to compare All the files in a directory & display the frequency of occurrenceawk比较目录中的所有文件并显示出现频率
【发布时间】:2015-05-08 20:32:51
【问题描述】:

假设在一个目录中我有 3 个文件,文件 1、文件 2 和文件 3。具有相同的标题名称 是否可以在awk中比较&写出现频率

File 1

C1  C2  C3  C4
a   d   a   d
a   d   a   d
a   d   a   d



File 2

C1  C2  C3  C4
a   d   a   d
a   v   a   d
a   d   a   d

File 3 

C1  C2  C3  C4
a   d   r   d
a   f   a   d
a   d   a   d

第 1 步比较文件 1 和文件 2

Temp.output

C1  C2  C3  C4
0   0   0   0
0   1   0   0
0   0   0   0

然后比较 File 2 & File 3 & overwrite Temp.output 与频率

Final.Output
C1  C2  C3  C4
0   0   1   0
0   2   0   0
0   0   0   0

原始目录可能包含多个文件,我希望每个文件都按顺序处理,即。 File1.txt 和 file2.txt 然后 file2.txt 和 file3.txt

【问题讨论】:

  • 它是否可以组成一个 4x4 矩阵,并且每当 (x, y) 处的单元格与文件 n 到 n+1 不同时,将结果单元格在 (x, y) 处递增?
  • 不,这只是为了视觉表现......让您了解变化发生在哪里。

标签: unix awk gawk


【解决方案1】:

让我建议您将输入文件转换为行。有了这个,你就可以轻松申请awk了。

paste -s <file> 命令是您的盟友。您可以在下面看到如何对文件进行排序并将它们转换为行:

$ cat File1.txt 
C1  C2  C3  C4
a   d   a   d
a   d   a   d
a   d   a   d
$ ls
File1.txt  File2.txt  File3.txt
$ ls | sort
File1.txt
File2.txt
File3.txt
$ ls | sort | xargs -L 1 -I {} /bin/bash -c 'echo -n {}" "; paste -s {}'
File1.txt C1  C2  C3  C4    a   d   a   d   a   d   a   d   a   d   a   d
File2.txt C1  C2  C3  C4    a   d   a   d   a   v   a   d   a   d   a   d
File3.txt C1  C2  C3  C4    a   d   r   d   a   f   a   d   a   d   a   d
$ 

一旦进入行,您可以使用 awk 来迭代字段(NF 会告诉您有多少)。我们将使用几个规则。

对于每一行,您将比较i 处的字段是否与之前保存的值不同,并相应地增加结果。跳过将第一行的结果与(NR != 1) 选择器进行比较。

(NR != 1) { for (i = 1; i <= NF; i++) { if (last[i] != $i) { result[i]++; } } }

在同一个 awk 调用中,包含更新保留最后值的数组的规则:

{ for (i = 1; i <= NF; i++) { last[i] = $i  }  }

最后打印出文件和结果的状态:

{ printf("%s", $1); for (i = 1; i <= NF; i++) { printf(" %d", result[i]) } print "" }

这是整个命令:

$ ls | sort | xargs -L 1 -I {} /bin/bash -c 'echo -n {}" "; paste -s {}' | awk '(NR != 1) { for (i = 1; i <= NF; i++) { if (last[i] != $i) { result[i]++; } } } { for (i = 1; i <= NF; i++) { last[i] = $i  }  } { printf("%s", $1); for (i = 1; i <= NF; i++) { printf(" %d", result[i]) } print "" }'
File1.txt 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
File2.txt 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
File3.txt 2 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0
$ 

此输出以文件名开头,然后是累积的差异:

  • 文件名(总是不同)
  • 列(C1、C2、C3、C4 始终相同)
  • 然后是你的 12 个值。您的相关数据从字段 7 开始。

您可以使用awk 在适当时插入新行来重新格式化:

awk '{ print ""; printf("%s", $1); for (i = 7; i <= NF; i++) { if (((i - 7) % 4) == 0) print "" ; printf(" %d", $i) } print "" }'

在这里你有一个完整的运行:

$ ls | sort | xargs -L 1 -I {} /bin/bash -c 'echo -n {}" "; paste -s {}' | awk '(NR != 1) { for (i = 1; i <= NF; i++) { if (last[i] != $i) { result[i]++; } } } { for (i = 1; i <= NF; i++) { last[i] = $i  }  } { printf("%s", $1); for (i = 1; i <= NF; i++) { printf(" %d", result[i]) } print "" }' | awk '{ print ""; printf("%s", $1); for (i = 7; i <= NF; i++) { if (((i - 7) % 4) == 0) print "" ; printf(" %d", $i) } print "" }'

File1.txt
 0 0 0 0
 0 0 0 0
 0 0 0 0

File2.txt
 0 0 0 0
 0 1 0 0
 0 0 0 0

File3.txt
 0 0 1 0
 0 2 0 0
 0 0 0 0
$ 

【讨论】:

    【解决方案2】:

    请在下面找到 awk 脚本。 row = 4 也包括标题

    #!/bin/bash
    /usr/bin/awk '{print $0;}' /tmp/file* | awk -v row=4 -v col=4 '
    {
        x = (NR - 1)%row;
        for(i = 1; i <= NF; i++){
            if(a[x, i] != $i){
                a[x, i] = $i;
                count[x, i]++;
            }
        }
    }END{
        for(i = 1; i <= row-1; i++){
            for(j = 1; j <= col; j++){
                printf (count[i, j]-1)" ";
            }
            printf "\n";
        }
    }'
    
    #

    下面的脚本是打印每次迭代

    #!/bin/bash
    
    /usr/bin/awk '{print $0;}' /tmp/stack/file* | awk -v row=4 -v col=4 '
    {
        x = (NR - 1)%row;
        for(i = 1; i <= NF; i++){
            if(a[x, i] != $i){
                a[x, i] = $i;
                count[x, i]++;
            }
        }
    
        for(i = 1; i <= row-1; i++){
                    for(j = 1; j <= col; j++){
                            printf (count[i, j]-1)" ";
                    }
                    printf "\n";
            }
        print "***********";
    
    }END{
        for(i = 1; i <= row-1; i++){
            for(j = 1; j <= col; j++){
                printf (count[i, j]-1)" ";
            }
            printf "\n";
        }
    }'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      • 2011-07-19
      • 2021-01-06
      • 2018-08-08
      • 2012-07-08
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多