我有一个类似于此文件的文件,我正在尝试验证每行的一个字段,如果该字段在文件中有重复,则添加一些文字。
\\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与相同的文件,如果它找到完全匹配的打印类似于“同一物理路径作为行#”的两种情况,
\\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发布于 2012-09-28 08:07:09
这里有一种使用GNU awk的方法。这是一个有点黑客,YMMV。运行方式如下:
awk -f script.awk file.txt{,}script.awk的内容
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
}
}结果:
\\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发布于 2012-09-28 07:34:03
这段代码解决了问题的一个简化版本。它标识与字段3中的前一行相比包含重复值的每一行。它不处理具有后续重复的行的标记。
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等(但您必须决定相同的名称是否可以出现在不同的文件中)。
它在给定的数据上几乎可以达到预期的效果:
\\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%的时间。
https://stackoverflow.com/questions/12631430
复制相似问题