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?


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.


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"

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"

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.


13

Experimente este código

Usar extname

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

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"

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

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+$/)

-5

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

File.dirname __FILE__

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.