Я пытаюсь использовать gsub в файле следующим образом:

def meth(*args, &blk)
  "non-replaced"
end

# "replaced string starting"
def meth(*args, &blk)
  "replaced"
end
# "replaced string ending"

def meth(*args, &blk)
  "non-replaced"
end

мой вопрос: Как заменить средний «мет» только эффективным способом, я могу сделать это глупым способом, например, realines > lines[from..to] > и затем lines.join( "\n"), это потратит слишком много времени, я надеюсь, эффективный способ, например, собственный метод для этого.

0
cimi3386284gt 3 Дек 2014 в 17:59
Какое условие для замены?
 – 
Aleksei Matiushkin
3 Дек 2014 в 18:14
Я не уверен, что правильно понял вопрос.
 – 
shevy
3 Дек 2014 в 20:38

2 ответа

Думаю, вам нужно что-то вроде этого:

contents = IO.read(filename)
replaced = contents.gsub(/# "replaced string starting"\n(.*)# "replaced string ending"/m, replace_contents)
IO.write(output_filename, replaced)

IO.read читает весь файл как одну текстовую строку, gsub(/.../m, replaced_contents) заменяет блок внутри двух комментариев тем, что вы хотели бы видеть вместо этого, и IO.write записывает его обратно в выходной файл.

0
Uri Agassi 3 Дек 2014 в 19:03

Вы должны найти маркеры или ориентиры в файле, который вы используете, чтобы включить обработку gsub, а затем снова отключить ее. Использование File.foreach позволяет легко читать файл построчно, что очень быстро и обеспечивает детализацию, необходимую для того, чтобы делать то, что вы хотите. (См. "Почему "глотание" файла не рекомендуется?" по причинам, по которым обычно следует избегать «прихлебывания» с использованием read или deadlines.)

В Ruby есть оператор .. (также известный как "flip-flop"), который предназначен для этой цели и позволяет очень легко обрабатывать только определенные фрагменты того, что вы перечисляете. См. "Почему оператор Flip-Flop включает второе условие?" и "Ruby — получить файл содержимое с разделителем в массиве", чтобы узнать, как его использовать.

Основная идея состоит в том, чтобы читать файл построчно, искать маркеры блоков и переключать обработку. Что-то вроде этого непроверенного кода является общей схемой для него:

File.open('/path/to/some/new_file.txt', 'w') do |fo|
  File.foreach('/path/to/some/file.txt') do |li|
    if (li[/some_start_pattern/] .. li[/some_stop_pattern/])
      li.gsub!(/pattern_of_thing_to_change/, 'text to substitute')
    end
    fo.puts li
  end
end

Делая это таким образом, вы можете легко увеличить количество блоков, которые вы обрабатываете в файле, или вещей, которые вы заменяете.

Назад к .. АКА "триггер". Это оператор, заимствованный из Perl, который получил его от AWK. Он запоминает состояние первого теста слева от .., и когда оно переключается на true, .. запоминает это и возвращает true до тех пор, пока второй тест не вернет true, после чего .. снова начинает возвращать false. Как только вы освоитесь, вы удивитесь, как быстро вы сможете захватывать куски файлов для обработки.

0
Community 23 Май 2017 в 14:57
Мой файл кажется пустым: find ./test -type f | xargs -d '\n' ruby ​​-e "ARGV.each do |filepath|; File.open(filepath, 'w') do |file|; File.foreach(filepath) do |line|; line.gsub(\ "установить\",\"последняя\"); строка file.puts; конец; конец; конец; "
 – 
user1767316
14 Окт 2020 в 12:03