帮助ruby脚本,(如果包含行,忽略)

时间:2011-08-12 13:19:22

标签: ruby

首先,让我道歉,因为我知道没有关于红宝石的事。我可以阅读代码并了解最新情况,但从未编写任何代码。

我有一个脚本,用于解析我们很久以前从某人那里获得的一些日志文件。

# 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 Inserts上抛出列数,最终导致查询失败,从而导致脚本失败。

我将如何实现这一目标?再次,抱歉成为一个完整的Noob与Ruby。我只是一个PHP家伙,甚至不擅长。洛尔

我知道,该地区可能必须在     data_lines.each do | r |

代码的位置,可能是if / then和一些正则表达式。谢谢你的帮助!

5 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分:1)

行后:

data_lines.each do |r|

添加:

next if r.match(/^VQM/)

答案 3 :(得分:1)

您最快的选择是其他人建议的(在单次迭代中跳过该行):

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

或者,你可以削减你的data_lines集合,使其只有正确的行。 (请注意下面的其他建议更改。)

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值,这是我们的返回值。

答案 4 :(得分:0)

<{1>} data_lines.each do |r|第一行应为

next if /^VQM/

这将导致下一次迭代立即开始(这与c中的continue语句相同)