Cómo obtener el nombre de archivo sin extensión de la ruta del archivo en Ruby

233

¿Cómo puedo obtener el nombre de archivo de una ruta de archivo en Ruby?

Por ejemplo, si tengo una ruta de acceso "C:\projects\blah.dll"y solo quiero el "bla".

¿Hay algún LastIndexOfmétodo en Ruby?

dagda1
fuente
3
Tenga en cuenta que no hay nada especial en un punto seguido de algunos (tres, tal vez) caracteres. Son parte del nombre del archivo. Algunos sistemas operativos marginales piensan que hay algo especial en esa parte de un nombre de archivo, pero no debe caer en esa trampa.
James Moore

Respuestas:

94
require 'pathname'

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

No he sido usuario de Windows en mucho tiempo, pero Pathname rdoc dice que no tiene problemas con los separadores de nombre de directorio en Windows.

NadieNada
fuente
86
No sé por qué esta es la respuesta n. ° 1 cuando File.basename no requiere un 'require' adicional de 'pathname'.
GroovyCakes
11
La clase pathnamefunciona con nombres de ruta locales mientras que Filesiempre asume nombres de ruta de Unix (la diferencia es la ruta y los separadores de unidad que se usan en MS Windows, por ejemplo)
nimrodm
3
A pesar de ser aceptado por el OP, esta respuesta en realidad no responde a la pregunta del OP. Ver las respuestas de Jonathan Lonowski y Arup Rakshit.
GSnyder
66
La extensión está presente si hay una. La respuesta es incorrecta.
Ludovic Kuty
44
No destroces tus propias publicaciones. ¡Gracias!
NobodyNada
586

Tratar File.basename

Devuelve el último componente del nombre de archivo dado en file_name, que debe formarse utilizando barras diagonales (`` / '') independientemente del separador utilizado en el sistema de archivos local. Si se proporciona el sufijo y está presente al final de file_name, se elimina.

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

En tu caso:

File.basename("C:\\projects\\blah.dll", ".dll")  #=> "blah"
Jonathan Lonowski
fuente
Con Linux y Ruby 1.8 trato de Pathname.new("some/path/to/my.file").basenameobtener my.file/: '(
java.is.for.desktop
67
Más genéricamente,File.basename("C:\\projects\\blah.dll", ".*") #=> "blah"
kelloti
La respuesta debería ser agregar la solución de @kelloti, que es mejor.
ymoreau
@kelloti: ¿Qué pasa /my/file.tar.gz?
Richard-Degenne
56

En caso de que no se conozca la extensión (necesita el 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
fuente
55
File.basename () es la respuesta!
sivabudh
26

Jonathan Lonowski respondió perfectamente, pero hay algo que ninguna de las respuestas menciona aquí. En lugar de File::extname, puede usar directamente a '.*'para obtener el nombre del archivo.

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

Pero, si desea obtener el nombre del archivo base de cualquier archivo de extensión específico , debe usarlo File::extname, de lo contrario no lo hará .

Arup Rakshit
fuente
13

Prueba este código

Utilizar extname

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

La respuesta de Jonathon es mejor, pero hacerle saber somelist[-1]es una de las LastIndexOfanotaciones disponibles.

Como krusty.ar mencionó somelist.lastaparentemente también lo es.

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
fuente
1
El problema con eso es que necesita saber si se trata de una barra invertida o una barra hacia adelante
Joseph Le Brech
4

Tenga en cuenta que las cadenas de comillas dobles se escapan.

'C:\projects\blah.dll'.split('\\').last
krusty.ar
fuente
55
Lo trata puramente como una cadena, en lugar de como una ruta, hace que el código sea menos portátil.
Boatcoder
Esto es mucho más complejo de lo necesario y es específico de Windows. Puedes solo File.basename. Y, como algunas de las otras respuestas, no responde la pregunta del OP.
Keith Bennett
0

Si tiene acceso a variables ENV, scancombinado con esta pequeña expresión regular (que encuentra la última pero una palabra, un punto, luego la última palabra de la cadena) pondrá el nombre del archivo en 'nombre de archivo':

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

Obviamente, puede usar scany la expresión regular en cualquier nombre de ruta que incluya el nombre de archivo, y __FILE__es la opción obvia:

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

Puede obtener la ruta del directorio al script actual con:

File.dirname __FILE__
Smar
fuente
La pregunta no era sobre la ruta, sino sobre el nombre del archivo . "¿Cómo puedo obtener el nombre del archivo de una ruta de archivo en Ruby?"
fontno
Eso sería:File.basename __FILE__
Samuel