Shell-Script

有效地 grep 已排序文件的間隔

  • February 8, 2019

我的文件有數百萬行,駐留在記憶體中/dev/shm/tmp.file,被多個執行緒訪問,看起來像這樣

831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file
4324,8d83c29e4d8c71bd66f1bd66fs,/path/to/another/file
...

,並按第二個之後的部分排序sort -t , -k3。一般來說,每一行都有形狀[0-9]*,[0-9a-z]*,.*,文件路徑可以包含除\0or之外的任何字元\n

我需要盡快提取駐留在給定目錄中的所有文件的行,而無需製作額外的副本。由於文件是以這種方式排序的,我正在尋找的行是文件的一個不間斷的塊。

目前我使用grep -F ',<directory>' /dev/shm/tmp.file,但我知道對第一個命中進行二進制搜尋然後逐行擴展塊或使用另一個二進制搜尋而不讀取每個新行的整個文件會更快。但是,這必須集成到 bash 腳本中,我發現無法在 bash 中執行類似 lseek 的操作。

sgrep但它需要對完整的行進行排序。

如何以',<directory>'比 更快的速度提取所有匹配項grep -F

**編輯:**輸入/dev/shm/tmp.file僅用於進行這種提取。因此,以某種方式對其進行預處理以使工作更容易是一種選擇。

編輯:a.b之間的排序不是問題,因為所有子目錄都應該包含在塊中。a``a/b

如果你831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file改為 /path/to/a/file,831092,25a1bd66f2eec71aa2f0a8bb3d

你可以這樣做:

look /path/to/ /dev/shm/tmp.file

look是 70 年代的傳統 Unix 實用程序,POSIX 未指定但相當普遍。在 Debian 及其衍生產品中,您會在bsdmainutils軟體包中找到一個,在 util-linux 中也有一個(也是從 BSD 複製的,不是在同名的 Debian 軟體包中)。

look mmap()s 文件並進行二進制搜尋。

但是請注意,grep除非您通過-b選項 (sigh),否則 Debian 實現將恢復為基本的線性搜尋。因此,在 Debian 或衍生產品上,您需要:

look -b /path/to/ /dev/shm/tmp.file

另請注意,某些實現對它們可以處理的文件大小有限制(請參閱 Debian 更新檔的相應錯誤

引用自:https://unix.stackexchange.com/questions/499306