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?


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.


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"

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"

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á .


13

Prueba este código

Utilizar extname

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

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"

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

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

-5

Puede obtener la ruta del directorio al script actual con:

File.dirname __FILE__

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.