Shell

檢查 sqlite 中不存在的模式

  • February 1, 2012

我用 Grep 上的純文字文件解釋了類似的情況,其中包含來自巨大文件的大量模式。那裡的很多人說我應該,所以現在我將我的數據遷移到 sqlite 數據庫:

我有一個文件,我從中提取了大約 10,000 個模式。然後我檢查數據庫是否不包含這樣的模式。如果沒有,我需要將它們保存在外部以file供進一步處理:

for id in $(grep ^[0-9] keys); do
 if [[ -z $(sqlite3 db.sqlite "select id from main where id = $id") ]]; then
   echo $id >>file
 fi
done

由於我是 SQL 新手,因此找不到簡單的方法來執行此操作。此外,這個循環是無用的,因為它比我awk在提到的 URL 上實現的慢 20 倍。

由於數據庫很大,不斷增長,而且我經常執行這個循環,是否有可能讓它更快?

對於每個模式,您都在呼叫sqlite重新連接到數據庫的程序的一個新實例。那是一種浪費。您應該建構一個查找任何鍵的查詢,然後執行該查詢。數據庫客戶端擅長執行大型查詢。

如果文件中的匹配行keys僅包含數字,則可以按如下方式建構查詢:

{
 echo 'select id from main where id in (';
 <keys grep -x '[0-9][0-9]*' |     # retain only lines containing only digits
 sed -e '1! s/^/, /' |             # add ", " at the beginning of every line except the first
 echo ');'
} | sqlite3 db.sqlite

對於更一般的輸入數據,您會明白:使用文本轉換來建構單個大型查詢。小心驗證您的輸入;在這裡,我們確保注入查詢的內容在語法上是有效的。上例中實際上存在一個極端情況:如果文件中沒有匹配項,則 SQL 語法無效;如果可能發生這種情況,您需要特別對待這種情況。這是處理空案例的更複雜的程式碼:

<keys grep -x '[0-9][0-9]*' |
if read first; then {
   echo 'select id from main where id in (' "$first"
   sed -e 's/^/, /'
   echo ');'
 } | sqlite3 db.sqlite
fi

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