2

我正在尝试自动化我通常手动完成的工作任务,即从多个用户的权限中获取数据库输出并比较它们以查看它们的共同点。我现在有一个使用 comm 和 paste 的脚本,但它并没有给我我想要的所有输出。

部分问题在于 comm 一次只处理两个文件,我需要至少比较三个文件才能找到趋势。我还需要确定三个中的两个是否有共同点,但第三个没有(因此比较两个 comm 命令的输出不起作用)。我需要这些以逗号分隔的值,以便可以将其导入 Excel。每个用户都有一个专栏,最后是他们共同拥有的所有内容的列表。如果 comm 可以比较两个以上的文件(并显示三分之二的比较),它将完美地工作。

除了代码之外,我还必须从原始 csv 文件中清除所有多余的内容,这是迄今为止我比较四个用户时所拥有的内容。这是非常低效的,但这是我所知道的。

cat foo1 | sort > foo5
cat foo2 | sort > foo6
cat foo3 | sort > foo7
cat foo4 | sort > foo8

comm foo5 foo6 > foomp
comm foo7 foo8 > foomp2

paste foomp foomp2 > output2
sed 's/[\t]/,/g' output2 > output4.csv
cat output4.csv

现在这会输出两个用户,他们的相似之处和不同之处,然后对另外两个用户执行相同的操作并将其粘贴在一起。这比手工做的效果更好,但我知道我可以做得更多。

一个示例输入文件将类似于:

用户 1

Active Directory
Internet
S: Drive
Sales Records

用户 2

Active Directory
Internet
Pricing Lookup
S: Drive

用户 3

Active Directory
Internet
Novell
Sales Records

他们有共同的 AD 和 Internet,三分之二的有销售记录访问权限和 S:驱动权限,每个只有一个有 Novell 和定价访问权限。

有人可以帮我解决我所缺少的吗?

4

3 回答 3

1

您可以使用该diff3程序。从手册页:

   diff3 - compare three files line by line

鉴于上面的示例输入,运行diff3结果为:

====
1:3,4c
  S: Drive
  Sales Records
2:3,4c
  Pricing Lookup
  S: Drive
3:3,4c
  Novell
  Sales Records

这会让你更接近你正在寻找的东西吗?

于 2012-05-01T13:31:48.917 回答
1

使用 GNU AWK ( gawk),您可以打印一个表格,显示多个用户的权限如何关联。你也可以用任何支持关联数组(哈希)的语言来做同样的事情,比如 Bash 4、Python、Perl 等。

#!/usr/bin/awk -f
{
    array[FILENAME, $0] = $0
    perms[$0] = $0
    if (length($0) > maxplen) {
        maxplen = length($0)
    }
    users[FILENAME] = FILENAME
}
END {
    pcount = asort(perms)
    ucount = asort(users)
    maxplen += 2
    colwidth = 8
    printf("%*s", maxplen, "")
    for (u = 1; u <= ucount; u++) {
        printf("%-*s", colwidth, users[u])
    }
    printf("\n")

    for (p = 1; p <= pcount; p++) {
        printf("%-*s", maxplen, perms[p])
        for (u = 1; u <= ucount; u++) {
            if (array[users[u], perms[p]]) {
                printf("%-*s", colwidth, "  X")
            } else {
                printf("%-*s", colwidth, "")
            }
        }
    printf("\n")
    }
}

保存此文件,可能称其为“相关”,然后将其设置为可执行:

$ chmod u+x correlate

然后,假设文件名对应于用户名或在其他方面有意义(您的示例是“user1”到“user3”,这样效果很好),您可以像这样运行它:

$ ./correlate user*

您将根据您的示例输入获得以下输出:

                  user1   user2   user3
Active Directory    X       X       X
Internet            X       X       X
Novell                              X
Pricing Lookup              X
S: Drive            X       X
Sales Records       X               X

编辑:

此版本不使用asort(),因此它应该适用于非 GNU 版本的 AWK。缺点是行和列的顺序是不可预测的。

#!/usr/bin/awk -f
{
    array[FILENAME, $0] = $0
    perms[$0] = $0
    if (length($0) > maxplen) {
        maxplen = length($0)
    }
    users[FILENAME] = FILENAME
}
END {
    maxplen += 2
    colwidth = 8
    printf("%*s", maxplen, "")
    for (u in users) {
        printf("%-*s", colwidth, u)
    }
    printf("\n")

    for (p in perms) {
        printf("%-*s", maxplen, p)
        for (u in users) {
            if (array[u, p]) {
                printf("%-*s", colwidth, "  X")
            } else {
                printf("%-*s", colwidth, "")
            }
        }
    printf("\n")
    }
}
于 2012-05-01T18:14:02.337 回答
0

我会使用 strings 命令从文件中删除任何二进制文件,将它们放在一起,然后在连接的文件上使用 uniq -c 来获取字符串的出现次数

于 2012-05-01T13:34:35.453 回答