Как получить имя файла без расширения из пути к файлу в Ruby

233

Как я могу получить имя файла из пути к файлу в Ruby?

Например, если у меня есть путь, "C:\projects\blah.dll"и я просто хочу "бла".

Есть ли LastIndexOfметод в Ruby?

dagda1
источник
3
Имейте в виду, что нет ничего особенного в точке, за которой следуют некоторые (возможно, три) символа. Они являются частью имени файла. Некоторые периферийные операционные системы считают, что в этой части имени файла есть что-то особенное, но вы не должны попадать в эту ловушку.
Джеймс Мур

Ответы:

94
require 'pathname'

Pathname.new('/opt/local/bin/ruby').basename
# => #<Pathname:ruby>

Я давно не был пользователем Windows, но rdoc Pathname говорит, что у него нет проблем с разделителями имен каталогов в Windows.

NobodyNada
источник
86
Я не знаю, почему это # ​​1 ранжированный ответ, когда File.basename не требует дополнительного 'require' из 'pathname'.
GroovyCakes
11
Класс pathnameработает с локальными путями, в то время как Fileвсегда принимает имена путей Unix (например, различие между разделителями пути и диска, которые используются в MS Windows)
nimrodm 21.12.12
3
Несмотря на то, что он принят ОП, этот ответ фактически не отвечает на вопрос ОП. См. Ответы Джонатана Лоновски и Арупа Ракшита.
GSnyder
6
Расширение присутствует, если оно есть. Ответ неверный.
Людовик Куты
4
Пожалуйста, не вандализируйте свои собственные сообщения. Спасибо!
NobodyNada
586

Пытаться File.basename

Возвращает последний компонент имени файла, указанный в file_name, который должен быть сформирован с использованием прямой косой черты (`` / '') независимо от разделителя, используемого в локальной файловой системе. Если суффикс задан и присутствует в конце имени_файла, он удаляется.

File.basename("/home/gumby/work/ruby.rb")          #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb")   #=> "ruby"

В твоем случае:

File.basename("C:\\projects\\blah.dll", ".dll")  #=> "blah"
Джонатан Лоновски
источник
С Linux и Ruby 1.8 я пытаюсь Pathname.new("some/path/to/my.file").basenameполучить my.file/: '(
java.is.for.desktop
67
Более обобщенно,File.basename("C:\\projects\\blah.dll", ".*") #=> "blah"
kelloti
Ответ должен быть добавлен решение @kelloti, что лучше.
ymoreau
@kelloti: Как насчет /my/file.tar.gz?
Ричард-Дежен
56

Если расширение неизвестно (для него требуется разделитель /):

irb(main):024:0> f = 'C:\foobar\blah.txt'.gsub("\\","/")
=> "C:/foobar/blah.txt"
irb(main):027:0> File.basename(f,File.extname(f))
=> "blah"
Винко Врсалович
источник
5
File.basename () является ответом!
Сивабуд
26

Джонатан Лоновски ответил отлично, но есть то, что ни один из ответов не упомянут здесь. Вместо этого File::extnameвы можете напрямую использовать '.*'для получения имени файла.

File.basename("C:\\projects\\blah.dll", ".*") # => "C:\\projects\\blah"

Но, если вы хотите получить базовое имя какого- либо конкретного файла расширения , вам нужно использовать File::extname, иначе нет.

Аруп Ракшит
источник
13

Попробуйте этот код

использование extname

 File.basename("a/b/d/test.rb", File.extname("a/b/d/test.rb")) #=> "test" 
Рахул Патель
источник
8

Ответ Джонатона лучше, но дать вам знать, somelist[-1]это одна из LastIndexOfдоступных обозначений.

Как упоминал krusty.ar somelist.lastвидимо тоже.

irb(main):003:0* f = 'C:\\path\\file.txt'
irb(main):007:0> f.split('\\')
=> ["C:", "path", "file.txt"]
irb(main):008:0> f.split('\\')[-1]
=> "file.txt"
monkut
источник
1
проблема в том, что вам нужно знать, является ли это обратной или прямой наклонной чертой
Джозеф Ле Брех,
4

Обратите внимание, что строки в двойных кавычках экранируют.

'C:\projects\blah.dll'.split('\\').last
krusty.ar
источник
5
Обрабатывает его исключительно как строку, а не как путь, что делает код менее переносимым.
кодек
Это намного сложнее, чем нужно, и зависит от Windows. Вы можете просто File.basename. И, как и некоторые другие ответы, не отвечает на вопрос ОП.
Кит Беннетт
0

Если у вас есть доступ к переменным ENV, в scanсочетании с этим небольшим регулярным выражением (которое находит последнее, кроме одного слова, точку, а затем последнее слово строки), имя файла будет помещено в «имя файла»:

filename = ENV['SCRIPT_NAME'].scan(/\w+\.\w+$/)

Очевидно, вы можете использовать scanи регулярное выражение для любого пути, который включает имя файла, и __FILE__это очевидный выбор:

__FILE__.scan(/\w+\.\w+$/)
Дейв Эверитт
источник
-5

Вы можете получить путь к каталогу к текущему скрипту с помощью:

File.dirname __FILE__
Smar
источник
Вопрос был не о пути, а о названии файла . "Как я могу получить имя файла из пути к файлу в Ruby?"
fontno
Это будет:File.basename __FILE__
Самуил