У меня есть два больших текстовых файла, checkums_1.txt и checkums_2.txt, я хочу проанализировать эти файлы и удалить дублирование между ними и объединить уникальные строки в один файл.
Каждый файл имеет следующую структуру для каждой строки.
размер, md5, путь
Пример: Checksums_1.txt
9565, a4fs614as6fas4fa4s46fsaf1, /mnt/app/1tier/2tier/filename.exe
9565, a4fs614as6fas4fa4s46fsaf1, /mnt/app/1tier/2tier/filename2.exe
Пример: Checksums_2.txt
9565, a4fs614as6fas4fa4s46fsaf1, /mnt/temp/1tier/2tier/filename.exe
9565, a4fs614as6fas4fa4s46fsaf1, /mnt/temp/1tier/2tier/filename2.exe
9565, a4fs614as6fas4fa4s46fsaf1, /mnt/temp/1tier/2tier/newfile.exe
Раздел, который должен использоваться для проверка между checkums_1.txt и checkums_2.txt выполняется после точки монтирования / mnt / app / и / mnt / temp /, другими словами, от начала каждой строки до конца точки монтирования / mnt / temp / или / mnt / app / будет игнорироваться.
Данные внутри checkums_1.txt являются более важными, поэтому, если найден дубликат, строка в checkums_1.txt должна быть перемещена в объединенный файл.
Часть Checksums_1.txt
1058,b8203a236b4f15316e516165a6546666,/mnt/app/Certificados/ca.crt
2694,8a815adefde4fa0c263e74832b15de64,/mnt/app/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/app/Certificados/ca.db.index
Часть Checksums_2.txt
1058,b8203a236b4f1531616318284202c9e6,/mnt/temp/Certificados/ca.crt
3,72b2ac90f7f3ff075a937d6be8fc3dc3,/mnt/temp/Certificados/ca.db.serial
2694,8a815adefde4fa0c263e74832b15de64,/mnt/temp/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/temp/Certificados/ca.db.index
Пример объединенного файла
1058,b8203a236b4f15316e516165a6546666,/mnt/app/Certificados/ca.crt
3,72b2ac90f7f3ff075a937d6be8fc3dc3,/mnt/temp/Certificados/ca.db.serial
2694,8a815adefde4fa0c263e74832b15de64,/mnt/app/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/app/Certificados/ca.db.index
Принятие обоих файлов не огромно, сценарий Python ниже сделает задание также.
Оба файла читаются сценарием. Строки в file_1 (файл, который имеет приоритет) разделяются каталогом, Вы ввели для файла в главном разделе (в Вашем примере /mnt/app/
).
Впоследствии, строки в file_1 записаны в выходной файл (объединенный файл). В то же время строки от file_2 удалены из списка строки, если строка идентификации (раздел после точки монтирования) происходит в строке. Наконец, "остающиеся" строки file_2 (которых никакая простофиля существуют в file_1) записаны в выходной файл также. Результат:
file_1:
1058,b8203a236b4f15316e516165a6546666,/mnt/app/Certificados/ca.crt
2694,8a815adefde4fa0c263e74832b15de64,/mnt/app/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/app/Certificados/ca.db.index
file_2:
1058,b8203a236b4f15316e516165a6546666,/mnt/app/Certificados/ca.crt
3,72b2ac90f7f3ff075a937d6be8fc3dc3,/mnt/temp/Certificados/ca.db.serial
2694,8a815adefde4fa0c263e74832b15de64,/mnt/app/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/app/Certificados/ca.db.index
объединенный:
1058,b8203a236b4f15316e516165a6546666,/mnt/app/Certificados/ca.crt
2694,8a815adefde4fa0c263e74832b15de64,/mnt/app/Certificados/ca.db.certs/01.pem
136,77bf2e5313dbaac4df76a4b72df2e2ad,/mnt/app/Certificados/ca.db.index
3,72b2ac90f7f3ff075a937d6be8fc3dc3,/mnt/temp/Certificados/ca.db.serial
#!/usr/bin/env python3
#---set the path to file1, file2 and the mountpoint used in file1 below
f1 = "/path/to/file_1"; m_point = "/mnt/app"; f2 = "/path/to/file_2"
merged = "/path/to/merged_file"
#---
lines1 = [(l, l.split(m_point)[-1]) for l in open(f1).read().splitlines()]
lines2 = [l for l in open(f2).read().splitlines()]
for l in lines1:
open(merged, "a+").write(l[0]+"\n")
for line in [line for line in lines2 if l[1] in line]:
lines2.remove(line)
for l in lines2:
open(merged, "a+").write(l+"\n")
merge.py
f1
(file_1
), f2
, путь к объединяющемуся файлу и точке монтирования, как упомянуто в file_1
.Выполните его командой:
python3 /path/to/merge.py
Или крошечный бит короче:
#!/usr/bin/env python3
#---set the path to file1, file2 and the mountpoint used in file1 below
f1 = "/path/to/file_1"; m_point = "/mnt/app"; f2 = "/path/to/file_2"
merged = "/path/to/merged_file"
#---
lines = lambda f: [l for l in open(f).read().splitlines()]
lines1 = lines(f1); lines2 = lines(f2); checks = [l.split(m_point)[-1] for l in lines1]
for item in sum([[l for l in lines2 if c in l] for c in checks], []):
lines2.remove(item)
for item in lines1+lines2:
open(merged, "a+").write(item+"\n")
Если Вы готовы использовать Python (поэтому, если производительность не является проблемой), что Вы хотите, может быть достигнут со следующим сценарием:
#!/usr/bin/env python3
import sys
import csv
import re
mountpoint1 = "/mnt/app/"
mountpoint2 = "/mnt/temp/"
if (len(sys.argv) != 4):
print('Usage: {} <input file 1> <input file 2> <output file>'.format(sys.argv[0]))
exit(1)
inputFileName1 = sys.argv[1]
inputFileName2 = sys.argv[2]
outputFileName = sys.argv[3]
# We place entries from both input files in the same dictionary
# The key will be the filename stripped of the mountpoint
# The value will be the whole line
fileDictionary = dict()
# First we read entries from file2, so that those
# from file2 will later overwrite them when needed
with open(inputFileName2) as inputFile2:
csvReader = csv.reader(inputFile2)
for row in csvReader:
if len(row) == 3:
# The key will be the filename stripped of the mountpoint
key = re.sub(mountpoint2, '', row[2])
# The value will be the whole line
fileDictionary[key] = ','.join(row)
# Entries from file1 will overwrite those from file2
with open(inputFileName1) as inputFile1:
csvReader = csv.reader(inputFile1)
for row in csvReader:
if len(row) == 3:
# The key will be the filename stripped of the mountpoint
key = re.sub(mountpoint1, '', row[2])
# The value will be the whole line
fileDictionary[key] = ','.join(row)
# Write all the entries to the output file
with open(outputFileName, 'w') as outputFile:
for key in fileDictionary:
outputFile.write(fileDictionary[key])
outputFile.write('\n')
Просто сохраните сценарий как merge-checksums.py
, дайте ему разрешение выполнения
chmod u+x merge-checksums.py
и выполненный это как:
./merge-checksums.py Checksums_1.txt Checksums_2.txt out.txt
bash
версия (с awk
и grep
):
#!/bin/bash
filename1="$1"
filename2="$2"
keys=$(awk -F'/' '{ for(i=4;i<NF;i++) printf "%s",$i "/"; if (NF) printf "%s",$NF; printf "\n"}' "$filename1" "$filename2" | awk '{gsub(/^[ \t]+|[ \t]+$/,"")};1' | sort -u)
while read -r key
do
match=$(grep "$key" "$filename1")
if [ "$match" != "" ]
then
echo "$match"
else
grep "$key" "$filename2"
fi
done <<< "$keys"
Checksums_1.txt
9565, 1111111111111111111111111, /mnt/app/1tier/2tier/filename.exe
9565, 0000000000000000000000000, /mnt/app/1tier/2tier/filename2.exe
Checksums_2.txt
9565, 2222222222222222222222222, /mnt/temp/1tier/2tier/filename.exe
9565, 0000000000000000000000000, /mnt/temp/1tier/2tier/filename2.exe
9565, 3333333333333333333333333, /mnt/temp/1tier/2tier/newfile.exe
Выполненный с
./merge_checksum Checksums_1.txt Checksums_2.txt > Checksums_3.txt
Checksums_3.txt
9565, 1111111111111111111111111, /mnt/app/1tier/2tier/filename.exe
9565, 0000000000000000000000000, /mnt/app/1tier/2tier/filename2.exe
9565, 3333333333333333333333333, /mnt/temp/1tier/2tier/newfile.exe
Или с входными файлами, которыми обмениваются,
./merge_checksum Checksums_2.txt Checksums_1.txt > Checksums_3.txt
Checksums_3.txt
9565, 0000000000000000000000000, /mnt/temp/1tier/2tier/filename2.exe
9565, 2222222222222222222222222, /mnt/temp/1tier/2tier/filename.exe
9565, 3333333333333333333333333, /mnt/temp/1tier/2tier/newfile.exe