我有兩個檔案。一個檔案disk.txt包含57665977行,database.txt包含39035203行;
為了測驗我的腳本,我制作了兩個示例檔案:
$ cat database.txt
01fffca9-05c8-41a9-8539-8bb2f587cef2
02fffd0d-fbcf-4759-9478-cfd32c987101
03fffd54-8d62-4555-a4ce-370f061048d5
04fffdb6-24f9-4b98-865f-ce32bc44872c
05fffe0c-2b9d-47fa-8ee9-2d20d0b28334
06fffea1-46f2-4aa2-93b9-be627189e38b
10ffff8a-cc20-4a2b-b9b2-a3cbc2000e49
11ffffaf-fd54-49f3-9719-4a63690430d9
12ffffc6-4ea8-4336-bdf1-e2d9d71a1c29
$ cat disk.txt
01fffca9-05c8-41a9-8539-8bb2f587cef2
02fffd0d-fbcf-4759-9478-cfd32c987101
03fffd54-8d62-4555-a4ce-370f061048d5
04fffdb6-24f9-4b98-865f-ce32bc44872c
05fffe0c-2b9d-47fa-8ee9-2d20d0b28334
06fffea1-46f2-4aa2-93b9-be627189e38b
07fffeed-5a0b-41f8-86cd-e6d99834c187
08ffff24-fb12-488c-87eb-1a07072fc706
09ffff29-ba3d-4582-8ce2-80b47ed927d1
10ffff8a-cc20-4a2b-b9b2-a3cbc2000e49
我試圖完成的是為差異創建檔案。
- disk.txt 中具有唯一性的檔案(因此我可以從磁盤中洗掉它們)
- 在 database.txt 中具有唯一性的檔案(所以我可以從備份和恢復中檢索它們)
用于comm檢索差異
我曾經comm看到這兩個檔案之間的差異。可悲的是comm,在一些獨特之后也回傳了重復。
$ comm -13 database.txt disk.txt
07fffeed-5a0b-41f8-86cd-e6d99834c187
08ffff24-fb12-488c-87eb-1a07072fc706
09ffff29-ba3d-4582-8ce2-80b47ed927d1
10ffff8a-cc20-4a2b-b9b2-a3cbc2000e49
$ comm -13 database.txt disk.txt
07fffeed-5a0b-41f8-86cd-e6d99834c187
08ffff24-fb12-488c-87eb-1a07072fc706
09ffff29-ba3d-4582-8ce2-80b47ed927d1
10ffff8a-cc20-4a2b-b9b2-a3cbc2000e49
comm在這些大檔案之一上使用需要 28,38 秒。這真的很快,但不是一個解決方案。
用于fgrep從comm結果中去除重復項
我可以用來fgrep從comm結果中洗掉重復項,這適用于示例。
$ fgrep -vf duplicate-plus-uniq-disk.txt duplicate-plus-uniq-database.txt
11ffffaf-fd54-49f3-9719-4a63690430d9
12ffffc6-4ea8-4336-bdf1-e2d9d71a1c29
$ fgrep -vf duplicate-plus-uniq-database.txt duplicate-plus-uniq-disk.txt
07fffeed-5a0b-41f8-86cd-e6d99834c187
08ffff24-fb12-488c-87eb-1a07072fc706
09ffff29-ba3d-4582-8ce2-80b47ed927d1
在大檔案上,這個腳本在一段時間后就崩潰了。所以這不是解決我的問題的可行選擇。
使用pythondifflib獲取唯一性
我嘗試使用從BigSpicyPotato在另一篇文章的回答中獲得的這個 python 腳本
import difflib
with open(r'disk.txt','r') as masterdata:
with open(r'database.txt','r') as useddata:
with open(r'uniq-disk.txt','w ') as Newdata:
usedfile = [ x.strip('\n') for x in list(useddata) ]
masterfile = [ x.strip('\n') for x in list(masterdata) ]
for line in masterfile:
if line not in usedfile:
Newdata.write(line '\n')
這也適用于示例。目前這仍在運行并占用了我的 CPU 資源。看看 uniq-disk 檔案,它也很慢。
問題
我可以在 bash / python 中嘗試任何更快/更好的選擇嗎?我也在調查awk/sed可能決議結果表格comm。
uj5u.com熱心網友回復:
來自man comm,*由我添加:
Compare **sorted** files FILE1 and FILE2 line by line.
您必須對檔案進行排序comm。
sort database.txt > database_sorted.txt
sort disk.txt > disk_sorted.txt
comm -13 database_sorted.txt disk_sorted.txt
查看man sort各種速度和記憶體增強選項,例如--batch-size, --temporary-directory --buffer-size --parallel。
在 disk.txt 中具有唯一性
的檔案 在 database.txt 中具有唯一性的檔案
排序后,您可以實作您的 python 程式,該程式逐行比較檔案并寫入提到的檔案,就像comm自定義輸出一樣。不要將整個檔案存盤在記憶體中。
你也可以用joinor來做一些事情comm --output-delimiter=' ':
join -v1 -v2 -o 1.1,2.1 disk_sorted.txt database_sorted.txt | tee >(
cut -d' ' -f1 | grep -v '^$' > unique_in_disk.txt) |
cut -d' ' -f2 | grep -v '^$' > unique_in_database.txt
uj5u.com熱心網友回復:
comm完全符合我的需要。我的 disk.txt 檔案的第 10 行后面有一個空格。因此 comm 將其作為唯一字串回傳。請查看@KamilCuk 答案以獲取有關排序檔案和使用通訊的更多背景關系。
uj5u.com熱心網友回復:
# WHINY_USERS=1 isn't trying to insult anyone -
# it's a special shell variable recognized by
# mawk-1 to presort the results
WHINY_USERS=1 {m,g}awk '
function phr(_) {
print \
"\n Uniques for file : { "\
(_)" } \n\n -----------------\n"
}
BEGIN {
split(_,____)
split(_,______)
PROCINFO["sorted_in"] = "@val_num_asc"
FS = "^$"
} FNR==NF {
______[ _____]=FILENAME
} {
if($_ in ____) {
delete ____[$_]
} else {
____[$_]=_____ ":" NR
}
} END {
for(__ in ______) {
phr(______[__])
_____=_<_
for(_ in ____) {
if( (___=____[_])== __) {
print " ", _____,_,
"(line "(substr(___,
index(___,":") !!__))")"
} } }
printf("\n\n") } ' testfile_disk.txt testfile_database.txt
|
Uniques for file : { testfile_disk.txt }
-----------------
1 07fffeed-5a0b-41f8-86cd-e6d99834c187 (line 7)
2 08ffff24-fb12-488c-87eb-1a07072fc706 (line 8)
3 09ffff29-ba3d-4582-8ce2-80b47ed927d1 (line 9)
Uniques for file : { testfile_database.txt }
-----------------
1 11ffffaf-fd54-49f3-9719-4a63690430d9 (line 18)
2 12ffffc6-4ea8-4336-bdf1-e2d9d71a1c29 (line 19)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/492670.html
上一篇:如何根據輸出過濾資料并執行命令
