Ruby, нужно прочитать содержимое файла и разбить его на новые файлы меньшего размера - PullRequest
0 голосов
/ 27 сентября 2011

У меня длинный файл с тоннами имен хостов с опциями.

что-то вроде

hostname {
   option 1
   option 2
   option 3
}

, файл имеет приблизительно 2000 имен хостов.то, что я хочу сделать в ruby, это:

открыть файл, начать чтение, когда я доберусь до имени хоста, создать файл с этим именем хоста и поместить эту же информацию из этого имени хоста только тогда, когда он достигнет} stop иперейти к следующему имени хоста / повторить

Ответы [ 3 ]

1 голос
/ 27 сентября 2011

Один из способов заставить это работать, если вы знаете, что {или} не будет в опции, - это использовать метод сканирования с режимом multiline на регулярном выражении:

b.scan( /([^\{]*)(\{)([^\}]*\n)*(\})/m)
=> [["a ", "{", "\n b\n c \n d\n", "}"], 
    ["\nB ", "{", "\n 1\n 2\n 3\n", "}"]]

вашему ре потребуется немного доработать, но это сработает, если вы захотите поместить все это в память для разбора. Запись в файл должна быть простой.

0 голосов
/ 27 сентября 2011

Мое решение:

actual_host = nil
#~ inputfile = File.open(filename)
inputfile = DATA #Only thi stestcase

inputfile.each_line{|line|
  case line
    when /\A\s*(\S+)\s*\{/
      filename = "#{$1}.txt" #write to <<hostname>>.txt
      raise "File already exist" if File.exist?(filename)
      actual_host = File.new(filename, 'w')
    when /\A\s*\}/
      actual_host = nil
    else  #copy data, if inside a host file
      actual_host << line if actual_host
      #Alternative without leading/trailing spaces
      #~ actual_host << line.strip if actual_host
    end
}

inputfile.close

__END__
hostname {
   option 1
   option 2
   option 3
}

Он анализирует построчно и запускает новый файл для каждого hostname { и закрывает его на }. Все промежуточное сохраняется в новый файл. если целевой файл уже существует, сценарий останавливается с исключением.

0 голосов
/ 27 сентября 2011

Для того, что вы опубликовали, я думаю, что-то вроде этого будет:

str = <<EOF
hostname1 {
  hi
}
hostname2 {
  how
}
hostname3 {
  are
}
EOF

hostnames = str.scan(/^\w+ {.*?}/m)
hostnames.each do |hostname|
    #here save it to a new file
    puts hostname
end

EDIT
Вот полный пример, он будет читать hostnames.cfg и сохранять отдельные файлы в папке с именем hostnames

hostnames.cfg

hostname1 {
  hi
}
hostname2 {
  how
}
hostname3 {
  are
}

whatever.rb

file = File.open('./hostnames.cfg', 'r')
content = file.readlines.join
file.close

hostnames = content.scan(/^\w+ {.*?}/m)
hostnames.each do |hostname|
    name = hostname.scan(/^\w+/m).first
    new = File.open("./hostnames/#{name}.cfg", "w+")
    new.write(hostname)
    new.close
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...