2016-12-19 3 views
1

У меня есть текстовый файл, как это:Удаление строки, содержащие определенные слова в текстовом файле в Рубине

User accounts for \\AGGREP-1 

------------------------------------------------------------------------------- 
Administrator   users     grzesieklocal 
Guest     scom      SUPPORT_8855 
The command completed successfully. 

Первая строка пустая строка. Я хочу удалить каждую пустую строку в этом файле и каждую строку, содержащую слова «Учетные записи пользователей», «-------», «Команда». Я хочу иметь только строки, содержащие пользователей. Я не хочу удалять только первые 4 и последние строки, потому что это может быть больше пользователей в некоторых системах, и файл будет содержать больше строк. загружает файл, используя

a = IO.readlines("test.txt") 

Есть ли способ удалить строки, содержащие определенные слова?

+0

http://stackoverflow.com/search?q=%5Bruby%5D+delete+line+in+file –

+0

Я не вижу проблемы с удалением первых четырех и последней одной строки - неважно, сколько строк между ними. Если вы хотите пойти unixy (и грязно), вы можете использовать 'IO.readlines (" | tail -n +4 test.txt | head -n -1 ")', но вы найдете лучшие и реальные ответы. – Felix

ответ

1

Solution

Эта структура читает файл строка за строкой, и написать новый файл непосредственно:

def unwanted?(line) 
    line.strip.empty? || 
    line.include?('User accounts') || 
    line.include?('-------------') || 
    line.include?('The command completed') 
end 

File.open('just_users.txt', 'w+') do |out| 
    File.foreach('test.txt') do |line| 
    out.puts line unless unwanted?(line) 
    end 
end 

Если вы знакомы с регулярным выражением, вы можете использовать:

def unwanted?(line) 
    line =~ /^(User accounts|------------|The command completed|\s*$)/ 
end 

Предупреждение из кода

сообщение появляется warning: string literal in condition при попытке использовать:

string = "nothing" 

if string.include? "a" or "b" 
    puts "FOUND!" 
end 

Он выводит:

parse_text.rb:16: warning: string literal in condition 
FOUND! 

Потому что это должно быть написано:

string = 'nothing' 

if string.include?('a') || string.include?('b') 
    puts "FOUND!" 
end 

См. Вопрос this для получения дополнительной информации.

1

IO::readlines возвращает массив, поэтому вы можете использовать Array#select, чтобы выбрать только нужные строки. Имейте в виду, что это означает, что весь ваш входной файл будет в памяти, что может быть проблемой, если файл действительно большой.

Альтернативный подход заключается в использовании IO::foreach, которая обрабатывает одну строку за один раз:

selected_lines = [] 
IO.foreach('test.txt') { |line| selected_lines << line if line_matches_your_requirements } 
+0

Было бы хорошо, но я не знаю, какие слова ищу. Файл - это вывод команды (сетевой пользователь), и я не знаю пользователей в системе. Но я знаю, что мне не нужны строки, содержащие конкретные слова. После удаления этих строк я могу легко использовать только имена пользователей. – mila002

+0

Вы используете 'foreach', чтобы избежать получения огромного массива, а затем вы создаете возможно огромный массив с' selected_lines';) –

+0

@ mila002, тогда ваши критерии заключаются в том, что строки не содержат конкретных слов! Выбор и удаление - это то же самое, что и применение обратных критериев (например, '! Line_starts_with_dash (строка)' vs 'line_starts_with_dash (строка)'). – Felix

Смежные вопросы