提问人:Jayadevan 提问时间:11/10/2023 最后编辑:markp-fusoJayadevan 更新时间:11/11/2023 访问量:57
如何检查特定位置的文件之间是否存在重复值
How do I check if there are duplicate values across files at a specific position
问:
我在 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 编号,但输出没有文件名。我的计划是剪切,获取文件名以及发票编号,在输出上做一个唯一的选择等。
答:
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 将发票联接到文件名。
对结果进行排序,删除同一文件的重复项。
仅打印发票/文件名顺序中重复的发票。
评论