Como obter o nome do arquivo sem extensão do caminho do arquivo em Ruby

233

Como posso obter o nome do arquivo de um caminho de arquivo no Ruby?

Por exemplo, se eu tenho um caminho de "C:\projects\blah.dll"e só quero o "blá".

Existe um LastIndexOfmétodo no Ruby?

dagda1
fonte
3
Lembre-se de que não há nada de especial em um ponto seguido por alguns (três, talvez) caracteres. Eles fazem parte do nome do arquivo. Alguns sistemas operacionais periféricos acham que há algo de especial nessa parte de um nome de arquivo, mas você não deve cair nessa armadilha.
James Moore

Respostas:

94
require 'pathname'

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

Não sou usuário do Windows há muito tempo, mas o nome do caminho diz que não há problemas com os separadores de nome de diretório no Windows.

Ninguém
fonte
86
Não sei por que essa é a resposta classificada como nº 1 quando File.basename não requer um 'requesito' adicional de 'nome do caminho'.
precisa saber é o seguinte
11
Classe pathnamefunciona com caminhos locais enquanto Fileassume sempre caminhos Unix (diferença é de caminho e separadores de accionamento que são usados em MS Windows, por exemplo)
nimrodm
3
Apesar de ter sido aceita pelo OP, essa resposta não responde de fato à pergunta do OP. Veja as respostas de Jonathan Lonowski e Arup Rakshit.
GSnyder #
6
A extensão está presente se houver uma. A resposta está errada.
Ludovic Kuty
4
Por favor, não vandalize suas próprias postagens. Obrigado!
NobodyNada 1/11
586

Experimentar File.basename

Retorna o último componente do nome do arquivo fornecido em file_name, que deve ser formado usando barras (`` / ''), independentemente do separador usado no sistema de arquivos local. Se o sufixo for fornecido e presente no final de file_name, ele será removido.

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

No seu caso:

File.basename("C:\\projects\\blah.dll", ".dll")  #=> "blah"
Jonathan Lonowski
fonte
Com o Linux e o Ruby 1.8, tento Pathname.new("some/path/to/my.file").basenameobter my.file/: '(
java.is.for.desktop
67
Mais genericamente,File.basename("C:\\projects\\blah.dll", ".*") #=> "blah"
kelloti
A resposta deve ser a solução de @kelloti que é melhor.
ymoreau
@kelloti: Que tal /my/file.tar.gz?
Richard-Degenne 6/09/19
56

Caso a extensão não seja conhecida (precisa do separador /):

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"
Vinko Vrsalovic
fonte
5
File.basename () é a resposta!
sivabudh
26

Jonathan Lonowski respondeu perfeitamente, mas há algo que nenhuma das respostas mencionadas aqui. Em vez de File::extname, você pode usar diretamente a '.*'para obter o nome do arquivo.

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

Mas, se você deseja obter o nome do arquivo base de qualquer arquivo de extensão específico , precisará usar File::extname, caso contrário não.

Arup Rakshit
fonte
13

Experimente este código

Usar extname

 File.basename("a/b/d/test.rb", File.extname("a/b/d/test.rb")) #=> "test" 
Rahul Patel
fonte
8

A resposta de Jonathon é melhor, mas informar você somelist[-1]é uma das LastIndexOfanotações disponíveis.

Como o krusty.ar mencionou, somelist.lastaparentemente também é.

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
fonte
1
problema com isso é que você precisa saber se é uma barra invertida ou forwardslash
Joseph Le Brech
4

Observe que as aspas duplas escapam \ 's.

'C:\projects\blah.dll'.split('\\').last
krusty.ar
fonte
5
Trata-o puramente como uma string, e não como um caminho, torna o código menos portátil.
usar o seguinte código
Isso é muito mais complexo do que o necessário e é específico do Windows. Você pode apenas File.basename. E, como algumas das outras respostas, não responde à pergunta do OP.
Keith Bennett
0

Se você tiver acesso às variáveis ​​ENV, scancombinadas com este pequeno regex (que encontra a última, mas uma palavra, um ponto, a última palavra da string) colocará o nome do arquivo em 'filename':

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

Obviamente, você pode usar scane a regex em qualquer nome de caminho que inclua o nome do arquivo e __FILE__é a escolha óbvia:

__FILE__.scan(/\w+\.\w+$/)
Dave Everitt
fonte
-5

Você pode obter o caminho do diretório para o script atual com:

File.dirname __FILE__
Smar
fonte
A pergunta não era sobre o caminho, era sobre o nome do arquivo . "Como posso obter o nome do arquivo em um caminho no Ruby?"
Font-
Isso seria:File.basename __FILE__
Samuel