2011-08-12 63 views
3

首先,讓我道歉,因爲我知道沒有關於紅寶石。我可以通讀代碼並理解發生了什麼,但從未寫過任何代碼。幫助紅寶石腳本,(如果行包含,忽略)

我有一個腳本,我們用它來解析一些很久以前從別人那裏獲得的日誌文件。

# format the csv data into an sql insert query 
def FormatToSQL(file_name) 
    $logger.info(caller) { "creating SQL insert q's" } 
    formatted_data = [] 
    data_lines = [] 
    open("#{LOCAL_DIR}/#{file_name}") { |f| data_lines = f.readlines } 
    data_lines.each do |r| 
    data = [] 
    rdata = r.split(' ') 
    rdata.each { |e| data.push("'#{e}'") } 
    data.unshift('DEFAULT') 
    sql_data = data.join(',') 
    formatted_data.push(sql_data) 
    end 
    return(formatted_data) 
end 
# ------------------------------------------------------------------- 
# ------------------------------------------------------------------- 
# M A I N 

$logger = Logger.new("//var/www/metaquery/calllogger.log", 3, 1024000) 
$logger.info(caller) { "start" } 
now = Time.now().gmtime() - 3600 ## files are name using UTC 
file_name = sprintf("calllog_%s_%02d_%02d_%02d.log", now.year, now.month.to_i,  now.day.to_i, now.hour.to_i) 
if(doSFTPPull(file_name)) then 
    ConnectDB() 
    formatted_sql = FormatToSQL(file_name) 
    formatted_sql.each { |sql| $local_conn.query("insert into #{DB_TABLE} values(#{sql})") } 
else 
    # we did not download the new file, report to ??? 
    false 
end 
$logger.info(caller) { "normal end" } 
# ------------------------------------------------------------------- 

日誌包含成千上萬的記錄行,像這樣

2xx3xx2xx7 2xx3xx56xx 07/28/11.19:55:45 19:55:46 20:00:00 2 4092 - - N - - TER - A T - 

但是,我們啓用了一些新的QoS數據統計,並增加了線路這樣,

VQM: 2xx3xx00xx 08/12/11.13:02:07 - - - - 20ms 0 0 

我想添加一條語句以忽略以VQM開頭的分段,因爲這會在MySQL插入時拋出列計數,最終導致查詢失敗,從而導致腳本失敗。

我該如何實現這個目標?同樣,對於成爲一個完整的紅寶石Noob抱歉。我只是一個PHP的傢伙,甚至沒有那麼好。大聲笑

我知道,該地區可能必須在 data_lines.each do | r |

其中代碼將是,並可能是如果/然後與一些正則表達式。謝謝你的幫助!

回答

4

試着這麼做:

data_lines.each do |r| 
    next if r.match(/^VQM/) #will skip this one if the line starts VQM 
    #everything else as before 
end 
+1

或者更簡潔地說:'如果旁邊R =〜/^VQM /' – Phrogz

+1

@Phrogz是啊,這太:)我永遠記得這反過來等號和波浪走在運營商:/ – Skilldrick

+0

@Skilldrick:一個辦法記得是認爲'=〜'開頭'=',因爲它比較兩個字符串不modyfing他們,而運營商則像'+ ='或'* ='都在左側,將修改離開 – Mchl

0

data_lines.each do |r|的第一行應該是

next if /^VQM/ 

這將導致下一次迭代立即開始(這是C相同continue語句)

+0

該死!你打敗了我! (但你沒有檢查線...) – Skilldrick

+0

我相信這裏的「r」是隱含的(就像perl的$ _) – ennuikiller

+0

嗯,我站在更正!我從來沒有使用過的Perl所以我寫的Ruby更喜歡的Python比Perl :) – Skilldrick

1
data_lines.each do |r| 
    next if r[0,4] == 'VQM:' 
    data = [] 
    rdata = r.split(' ') 
    rdata.each { |e| data.push("'#{e}'") } 
    data.unshift('DEFAULT') 
    sql_data = data.join(',') 
    formatted_data.push(sql_data) 
    end 

或者

data_lines.reject{|line| line[0,4] == 'VQM:'}.each do |r| 
    data = [] 
    rdata = r.split(' ') 
    rdata.each { |e| data.push("'#{e}'") } 
    data.unshift('DEFAULT') 
    sql_data = data.join(',') 
    formatted_data.push(sql_data) 
end 
1

行後:

data_lines.each do |r| 

地址:

next if r.match(/^VQM/) 
1

你最快的選擇是其他人所說的內容(跳過單一迭代期間行):

data_lines.each do |r| 
    next if r =~ /^VQM/ 
end 

或者,您可以削減您的一組data_lines t o只有首先有正確的線。 (請注意下面的其他建議更改。)

def FormatToSQL(file_name) 
    $logger.info(caller) { "creating SQL insert q's" } 
    formatted_data = [] 

    # Use IO.readlines to more simply slurp your values 
    data_lines = IO.readlines(File.join(LOCAL_DIR,file_name)) 

    # Modify the array, throwing out lines where this does not return false/nil 
    data_lines.reject!{ |r| r =~ /^VQM/ } 

    # modify the array, throwing out trailing newlines per line; 
    # invokes the .chomp method on each item in the array and uses the 
    # result of that as the new value for the array 
    data_lines.map!(&:chomp) 

    data_lines.each do |r| 
    data = r.split(' ').map{ |e| "'#{e}'" } 
    data.unshift('DEFAULT') 
    formatted_data << data.join(',') 
    end 

    # It is idiomatic (and slightly faster) to not use the 'return' keyword 
    # since the last value of your method _is_ what is returned. 
    formatted_data 
end 

最後,這裏就是我會親自寫你的方法,採用了更爲實用的風格:

def FormatToSQL(file_name) 
    $logger.info(caller) { "creating SQL insert q's" } 

    IO.readlines(File.join(LOCAL_DIR,file_name)).map do |line| 
    unless line =~ /^VQM/ 
     [ 
     'DEFAULT', 
     *line.chomp.split(' ').map{ |e| "'#{e}'" } 
     ].join(',') 
    end 
    end.compact 
end 

我們將文件映射到新值的每一行,除非符合VQM開始;在這種情況下,塊的結果是nil,並.compact最終呼叫從作爲退貨值數組中刪除所有nil值。