Проверьте, содержит ли файл строку
Итак, я нашел этот вопрос здесь, но у меня возникла проблема с выходом и как обрабатывать его с помощью оператора if. Это то, что у меня есть, но он всегда говорит, что это правда, даже если монитор слов не существует в файле
if File.readlines("testfile.txt").grep(/monitor/)
do something
end
Должно ли это быть что-то вроде == "nil"? Я совершенно новичок в рубине и не уверен в том, какие будут результаты.
Ответы
Ответ 1
Перечислимый # grep не возвращает логическое; он возвращает массив (как бы у вас был доступ к совпадениям без передачи блока в противном случае?).
Если совпадений не найдено, он возвращает пустой массив, а []
- true
. Вам нужно будет проверить размер массива в инструкции if
, т.е.:
if File.readlines("testfile.txt").grep(/monitor/).size > 0
# do something
end
Документация должна быть вашим первым ресурсом для таких вопросов.
Ответ 2
Я бы использовал:
if File.readlines("testfile.txt").grep(/monitor/).any?
или
if File.readlines("testfile.txt").any?{ |l| l['monitor'] }
Использование readlines
имеет проблемы с масштабируемостью, хотя при чтении всего файла в массив. Вместо этого использование foreach
выполнит то же самое без проблемы масштабируемости:
if File.foreach("testfile.txt").grep(/monitor/).any?
или
if File.foreach("testfile.txt").any?{ |l| l['monitor'] }
См. "Почему "сглаживание" файла не является хорошей практикой? для получения дополнительной информации о проблемах масштабируемости.
Ответ 3
Grep даст вам массив всех найденных "мониторов". Но вам не нужен массив, вы хотите логическое: есть ли в этом файле строка "monitor"?
Этот файл читает как можно меньше файла:
if File.open('test.txt').lines.any?{|line| line.include?('monitor')}
p 'do something'
end
readlines читает весь файл, строки возвращают перечислитель, который делает это по строкам.
Ответ 4
если кто-либо ищет решение для отображения последней строки файла, где эта строка возникает, просто
File.readlines('dir/testfile.txt').select{|l| l.match /monitor/}.last
Пример
файл:
monitor 1
monitor 2
something else
вы получите
monitor 2