0

ユーザー入力に基づいて特定の文字列を見つけるためにファイルを検索する方法を見つけましたが、見つけた文字列を削除する方法がわかりません。さまざまな grep メソッドを見てきましたが、それらを入力/出力に変更する方法がわからないため、次のようになりました。

puts "Enter media to delete";
characters = gets.chomp;

File.open("arraystarter.rb").each { |line| 
  unless characters.each_char.map  { |c| line.include?(c) }.include? false
    puts "Did you mean #{line}?";
  intent = gets.chomp.downcase
  case intent
  when 'yes'
  # TODO: Delete the line I've found
   puts "#{line} deleted!"
  when 'no'
  puts "Nevermind, then."
  end
  end
    }

「はい」の後に puts/"deleted" 行を置き換える必要がありますが、どうすればよいですか?

4

3 に答える 3

1

あなたの質問に対するかなり良い解決策を見つけました。それは少し複雑です。ファイルを文字列に変換してから配列に変換し、未処理の行を削除してから、配列をファイルに出力します。私はあなたの小さなコードを、ユーザー入力が含まれる行数を見つける真のスクリプトに変換し、それらをすべて削除するか、1 つだけ削除するかを尋ねます。コードをこのバージョンに持ち込むのに少し時間がかかりましたが、私はチャレンジが好きです (「チャレンジ? これ?」と考えて笑ってしまうかもしれません.... まあ、私にとってはチャレンジでした。 Rubyについて学びます)。それが役に立てば幸い...

puts "Enter media to delete:"
characters = gets.chomp()
filename = "arraystarter.rb"
counts = 0

file_open = File.readlines(filename, 'rb')
file_to_string = file_open.map(&:inspect).join(',')
string = file_to_string.delete "\""
$array = string.split(/\\r/)
$array = string.split(/\\n/)

$array.map do |l|
  c = l.include? "#{characters}"
  counts += 1 if c == true
  next if c == true
end

def delete_all(characters)
  $array.each do |l|
  l.replace("") if l.include? characters
end
end

def puts_what(ct, l, c)
  if ct == 1 then puts "Did you mean #{l}?"
  else puts "#{c} exist in #{ct} lines. Do you want to delete all of them or just #{l}?" end
end

if string.include? "#{characters}"
  $array.each do |row|
  if row.include? "#{characters}" then puts_what(counts, row, characters)
    intent = gets.chomp()
    if intent == "yes"
      $array.delete row
      open_again = File.open(filename, 'w+')
      open_again.puts $array
      open_again.close()
      puts "#{row} deleted!"
      break
    elsif intent == "all"
      if counts == 1 then break end
      delete_all(characters)
      $array.delete ""
      open_once_more = File.open(filename, 'w+')
      open_once_more.puts $array
      open_once_more.close()
      puts "All the lines that contain #{characters} are deleted!"
      break
    elsif intent == "no" then puts "Never mind, then."
    end
  end
  end
else
  puts "Can't find #{characters}"
end

それは 100% 完璧に動作します! このスクリプトの唯一の欠点は、常にファイルの最後に空白行が残ることですが、問題がなければスクリプトを問題なく使用できます。

PS: インプレース編集を使用するため、大きなファイルにはお勧めできません。リソースを消費します。

PPS: 私のスクリプトは長くて複雑なので、上級の Ruby プログラマーが私のスクリプトを改善したい場合は、大歓迎です!

于 2013-07-20T13:08:57.163 に答える
0

必要に応じて、 を使用して、見つかった単語または単語を nil に置き換え、効果的に「削除」することができますsub('some text', '')sub

于 2013-05-15T23:41:58.280 に答える
0

UNIX フレーバー マシン (Linux、Mac OS X) でコードを実行している場合、システム コールで sed コマンドをチートして使用できます。

puts "Enter media to delete";
characters = gets.chomp;

system("sed s/#{characters}// arraystarter.rb > output.rb")

これを純粋な Ruby で実行して高性能にする必要がある場合は、Google の「Knuth–Morris–Pratt アルゴリズム」またはこのサンプル コードを参照してください。

これがある種の宿題の演習である場合、これらの提案はどちらも進むべき道ではありません.

于 2013-05-16T04:23:52.250 に答える