簡體   English   中英

在 Unix 中使用正則表達式連接兩個文件(最好使用 perl)

[英]Joining two files with regular expression in Unix (ideally with perl)

我有以下兩個文件disconnect.txt和answered.txt:

斷開連接.txt

2011-07-08 00:59:06,363 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:459 - AnalyzedInfo had ActCode = Disconnected from: 40397400012 to:40397400032
2011-07-08 00:59:06,363 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:459 - AnalyzedInfo had ActCode = Disconnected from: 4035350012 to:40677400032

回答.txt

2011-07-08 00:59:40,706 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:404 - Normal Call Answered, billingid=2301986 from: 40397643433 to:403###34**
2011-07-08 00:59:40,706 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:404 - Normal Call Answered, billingid=2301986 from: 3455334459 to:1222
2011-07-08 00:59:48,893 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:404 - Normal Call Answered, billingid=2220158 from: 4035350012 to:40677400032

我想根據 from: 和 to: 字段在這些文件上創建一個連接,並且 output 應該是 answer.txt 中的匹配字段。 例如,在上述兩個文件中,output 將是:

2011-07-08 00:59:48,893 [socketProcessor] DEBUG ProbeEventDetectorIS41Impl:404 - Normal Call Answered, billingid=2220158 from: 4035350012 to:40677400032

我目前正在通過將文件 1 中的每一行與文件 2 中的每一行進行比較來做到這一點,但想知道是否存在有效的方法(這些文件將以數十 GB 為單位)。

謝謝

聽起來你有數億行?

除非文件的排序方式使您可以期望 from: 和 to: 的順序至少模糊相關,否則這是數據庫的工作。

如果文件很大,二次算法將需要一個生命周期。

這是一個 Ruby 腳本,它只使用了一個 hash 表在 answered.txt 中的每行查找:

def key s
  s.split('from:')[1].split('to:').map(&:strip).join('.')
end

h = {}
open 'disconnect.txt', 'r' do |f|
  while s = f.gets
    h[key(s)] = true
  end
end

open 'answered.txt', 'r' do |f|
  while a = f.gets
    puts a if h[key(a)]
  end
end

就像ysth所說,這完全取決於 disconnect.txt 中的行數。 如果這是一個非常大的1數字,那么您可能無法容納 memory 中的所有鍵,並且您將需要一個數據庫。


1.disconnect.txt中的行數乘以(大約)64應該小於你機器中memory的數量。

首先,如果文件尚未以這種方式排序,則對從/到時間戳上的文件進行排序。 (是的,我知道從/到似乎存儲為紀元秒,但這仍然是一個時間戳。)

然后取出排序的文件並比較每個文件的第一行。

  • 如果時間戳相同,則您有匹配項。 萬歲。 在一個或兩個文件中推進一行(取決於每個文件中重復時間戳的規則)並再次比較。
  • 如果不是,請獲取具有較早時間戳的文件中的下一行並再次比較。

這是比較兩個(或更多)已排序文件的最快方法,它保證不會從磁盤中多次讀取任何行。

如果您的文件未正確排序,那么對於“每個數十 GB”大小范圍內的文件,初始排序操作可能會有些昂貴,但是:

  1. 您可以將文件拆分為任意大小的塊(理想情況下,每個塊都小到足以放入內存),獨立地對每個塊進行排序,然后將上述算法從兩個文件推廣到所需的任意數量。
  2. 即使您不這樣做並且您處理排序文件所涉及的磁盤抖動,該文件大於可用的 memory,排序然后對每個文件執行單次傳遞仍然任何涉及笛卡爾連接的解決方案快得多。

或者您可以只使用前面答案中提到的數據庫。 上述方法在大多數(如果不是全部)情況下會更有效,但是基於數據庫的解決方案會更容易編寫,並且還可以為以其他方式分析數據提供很大的靈活性,而無需進行完整的掃描每次您需要訪問其中的任何內容時,每個文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM