首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Awk -比较每一行以找到重复的字段,并在行尾添加一些文字

Awk -比较每一行以找到重复的字段,并在行尾添加一些文字
EN

Stack Overflow用户
提问于 2012-09-28 07:17:22
回答 2查看 1.1K关注 0票数 2

我有一个类似于此文件的文件,我正在尝试验证每行的一个字段,如果该字段在文件中有重复,则添加一些文字。

代码语言:javascript
复制
\\FILE04\BUET-PCO;\\SERVER24\DFS\SHARED\CORP\ET\PROJECT CONTROL OFFICE;/FS7_150a/FILE04/BU-D/PROJECT CONTROL OFFICE;10000bytes;9888;;;
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\DFS\SHARED\CAN\AGENCY\GOLDMINE;/FS3_150a/FILE12/BU/AGENCY/GOLDMINE;90000bytes;98834;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;other stuff;;

在我的示例中,第3行和第4行具有相同的物理路径。我希望有一个脚本,它可以比较第三个字段,例如/FS3_150a/FILE12/BU/GB/BUSINTEG与相同的文件,如果它找到完全匹配的打印类似于“同一物理路径作为行#”的两种情况,

代码语言:javascript
复制
\\FILE04\BUET-PCO;\\SERVER24\DFS\SHARED\CORP\ET\PROJECT CONTROL OFFICE;/FS7_150a/FILE04/BU-D/PROJECT CONTROL OFFICE;10000bytes;9888;;;
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\DFS\SHARED\CAN\AGENCY\GOLDMINE;/FS3_150a/FILE12/BU/AGENCY/GOLDMINE;90000bytes;98834;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;;;Same Physical Path as Line #4
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;other stuff;; Same Physical Path as Line #3
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-28 08:07:09

这里有一种使用GNU awk的方法。这是一个有点黑客,YMMV。运行方式如下:

代码语言:javascript
复制
awk -f script.awk file.txt{,}

script.awk的内容

代码语言:javascript
复制
BEGIN {
    FS = ";"
}

FNR==NR {
    array[$3]=array[$3] "#" NR
    next
}

{
    if ($3 in array && array[$3] ~ /#.#/) {
        copy = array[$3]
        sub("#"FNR, "", copy)
        printf "%s Same Physical Path as Line as %s\n", $0, copy
    }
    else {
        print
    }
}

结果:

代码语言:javascript
复制
\\FILE04\BUET-PCO;\\SERVER24\DFS\SHARED\CORP\ET\PROJECT CONTROL OFFICE;/FS7_150a/FILE04/BU-D/PROJECT CONTROL OFFICE;10000bytes;9888;;;
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\DFS\SHARED\CAN\AGENCY\GOLDMINE;/FS3_150a/FILE12/BU/AGENCY/GOLDMINE;90000bytes;98834;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;;; Same Physical Path as Line as #4
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;other stuff;; Same Physical Path as Line as #3
票数 1
EN

Stack Overflow用户

发布于 2012-09-28 07:34:03

这段代码解决了问题的一个简化版本。它标识与字段3中的前一行相比包含重复值的每一行。它不处理具有后续重复的行的标记。

代码语言:javascript
复制
awk -F';' '{ tag = ""
             if (field3[$3] != 0) tag = " Same physical path as line " field3[$3]
             else field3[$3] = NR
             printf "%s%s\n", $0, tag
           }' "$@"

可能还有其他方法来组织它,但关键是使用关联数组field3来跟踪字段3中显示的名称以及第一次看到给定名称的行号。这假设您正在处理单个输入文件。如果您必须处理多个文件,请查找FNR等(但您必须决定相同的名称是否可以出现在不同的文件中)。

它在给定的数据上几乎可以达到预期的效果:

代码语言:javascript
复制
\\FILE04\BUET-PCO;\\SERVER24\DFS\SHARED\CORP\ET\PROJECT CONTROL OFFICE;/FS7_150a/FILE04/BU-D/PROJECT CONTROL OFFICE;10000bytes;9888;;;
\\FILE12\BUAG-GOLDMINE$;\\SERVER24\DFS\SHARED\CAN\AGENCY\GOLDMINE;/FS3_150a/FILE12/BU/AGENCY/GOLDMINE;90000bytes;98834;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;;;
\\FILE12\BUGB-BUSINTEG$;\\SERVER24\DFS\SHARED\CAN\GB\BUSINTEG;/FS3_150a/FILE12/BU/GB/BUSINTEG;50000bytes;988822;other stuff;; Same physical path as line 3

在第3行生成“标签”的困难在于预测未来;这很难。为此,您必须将整个文件存储到内存中,对字段3中出现给定值的行号进行标记(通常,这可能是一个广泛的行号列表),然后对数据进行迭代并进行适当的标记。虽然在awk中正确地组织数据可能也是可行的,但我更喜欢使用Perl to awk来完成这项工作。

如果是我,我应该可以完成90%的工作;带有重复项的行是可以识别的。如果您想要完成最后10%的工作,那么预计它将花费第一阶段计划的另外90%的时间。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12631430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档