如何检查特定位置的文件之间是否存在重复值

How do I check if there are duplicate values across files at a specific position

提问人:Jayadevan 提问时间:11/10/2023 最后编辑:markp-fusoJayadevan 更新时间:11/11/2023 访问量:57

问:

我在 Linux 服务器上的一个目录中有大约 2000 个文件。在每个文件中,位置 x-y 都有发票编号。检查这些文件之间是否存在重复项并打印文件名和值的最佳方法是什么?问题的简化版本——

$ cat a.txt 
xyz1234
xyz1234
pqr4567
$ cat b.txt 
lon9876
lon9876
lon4567

在上面的 2 个文件中,假设发票编号位于位置 4-8,我们有重复项 - a.txt 和 b.txt 中的“4567”。如果我们在同一个文件中有重复项 - 因为我们在 a.txt 中有 1234,这很好。无需打印。我试图剪切 inv 编号,但输出没有文件名。我的计划是剪切,获取文件名以及发票编号,在输出上做一个唯一的选择等。

Linux 文件 awk sed cut

评论

1赞 Toby Speight 11/10/2023
到目前为止,你尝试了什么?StackOverflow 希望您首先尝试解决自己的问题,因为您的尝试有助于我们更好地了解您的需求。请编辑问题以显示您尝试过的内容,并用最小的可重复示例显示您遇到的特定障碍。有关更多信息,请参阅如何提问

答:

1赞 choroba 11/10/2023 #1

Perl 来救援!

perl -lne '
    $in_file{ substr $_, 3, 4 }{$ARGV} = 1;
    END {
        for $invoice (%in_file) {
            print join "\t", $invoice, keys %{ $in_file{$invoice} }
                if keys %{ $in_file{$invoice} } > 1;
        }
    }
' -- *txt
  • -n逐行读取输入文件,运行每个文件的代码;
  • -l从输入中删除换行符并将其添加到 ed 行中;print
  • $ARGV包含当前打开的文件的名称;
  • 我们构建一个哈希值的哈希值,第一级键是发票号,第二级键是找到它的文件;
  • 有关如何提取发票编号的详细信息,请参阅 substr;
  • 在所有输入的末尾,我们打印具有多个文件关联的键(即发票编号)。
0赞 dawg 11/10/2023 #2

作为替代方案,这里有一个 Ruby 来做到这一点:

ruby -lne 'BEGIN{files=Hash.new {|h,k| h[k] = Set.new()} }
files[$_[3..6]]<<$<.file.path
END{
    files.each{|inv,names| puts "#{inv}=>#{names.join","}" if names.length>1} 
}
' a.txt ba.txt

或者使用 GNU awk(对于 ENDFILE 模式),您可以执行以下操作:

gawk '
BEGIN { FS = OFS = "," }

FNR == 1 { split("", fn, FS) } # clear array

{
    key = substr($0, 4, 4)
    if (! (key in fn)) {
        fn[key]
    }
}

ENDFILE {
    for (e in fn) {
        idx[e] = idx[e] ? idx[e] OFS FILENAME : FILENAME
    }
}

END {
    for (e in idx) {
        n = split(idx[e], a, FS)
        if (n > 1) {
            print e "=>" idx[e]
        }
    }
}
' *.txt

在示例中,任一打印:

4567=>a.txt,ba.txt
0赞 potong 11/11/2023 #3

这可能对你有用(GNU sed、sort、uniq 等):

echo *.txt |
xargs -n1 sed -E 's/...(.*)/\1 &/p;F;d' |
sed 'N;s/\n/ /' |
sort -u -k1n -k3 |
uniq -w4 -D

回显文件名。

使用 xargs 将 sed 脚本应用于每个文件,该文件将发票一分为二并附加文件名。

使用 sed 将发票联接到文件名。

对结果进行排序,删除同一文件的重复项。

仅打印发票/文件名顺序中重复的发票。