Comment obtenir un nom de fichier sans extension à partir du chemin de fichier dans Ruby

233

Comment puis-je obtenir le nom de fichier à partir d'un chemin de fichier dans Ruby?

Par exemple, si j'ai un chemin d'accès "C:\projects\blah.dll"et que je veux juste le "bla".

Existe-t-il une LastIndexOfméthode en Ruby?

dagda1
la source
3
Gardez à l'esprit qu'il n'y a rien de spécial dans un point suivi de quelques (trois, peut-être) caractères. Ils font partie du nom du fichier. Certains systèmes d'exploitation marginaux pensent qu'il y a quelque chose de spécial dans cette partie d'un nom de fichier, mais vous ne devriez pas tomber dans ce piège.
James Moore

Réponses:

94
require 'pathname'

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

Je n'ai pas été un utilisateur Windows depuis longtemps, mais le rdoc Pathname dit qu'il n'a aucun problème avec les séparateurs de noms de répertoire sur Windows.

PersonneNada
la source
86
Je ne sais pas pourquoi c'est la réponse classée n ° 1 lorsque File.basename ne nécessite pas un "require" supplémentaire de "pathname".
GroovyCakes
11
La classe pathnamefonctionne avec les chemins d'accès locaux tout Fileen supposant toujours les chemins d'accès Unix (la différence est les séparateurs de chemin et de lecteur qui sont utilisés dans MS Windows, par exemple)
nimrodm
3
Bien qu'elle soit acceptée par le PO, cette réponse ne répond pas réellement à la question du PO. Voir les réponses de Jonathan Lonowski et Arup Rakshit.
GSnyder
6
L'extension est présente s'il y en a une. La réponse est fausse.
Ludovic Kuty
4
Veuillez ne pas vandaliser vos propres messages. Merci!
NobodyNada
586

Essayer File.basename

Renvoie le dernier composant du nom de fichier donné dans nom_fichier, qui doit être formé à l'aide de barres obliques (`` / '') quel que soit le séparateur utilisé sur le système de fichiers local. Si le suffixe est donné et présent à la fin de nom_fichier, il est supprimé.

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

Dans ton cas:

File.basename("C:\\projects\\blah.dll", ".dll")  #=> "blah"
Jonathan Lonowski
la source
Avec Linux et Ruby 1.8, j'essaye d' Pathname.new("some/path/to/my.file").basenameobtenir my.file/: '(
java.is.for.desktop
67
Plus génériquement,File.basename("C:\\projects\\blah.dll", ".*") #=> "blah"
kelloti
La réponse devrait être d'ajouter la solution de @kelloti qui est meilleure.
ymoreau
@kelloti: Qu'en est-il /my/file.tar.gz?
Richard-Degenne
56

Dans le cas où l'extension n'est pas connue (elle a besoin du séparateur /):

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
la source
5
File.basename () est la réponse!
sivabudh
26

Jonathan Lonowski a répondu parfaitement, mais il y a quelque chose qu'aucune des réponses mentionnées ici. Au lieu de File::extname, vous pouvez directement utiliser un '.*'pour obtenir le nom du fichier.

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

Mais, si vous souhaitez obtenir le nom de fichier de base de tout fichier d' extension spécifique , vous devez utiliser File::extname, sinon.

Arup Rakshit
la source
13

Essayez ce code

Utilisation extname

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

La réponse de Jonathon est meilleure, mais vous en informer somelist[-1]est l'une des LastIndexOfnotations disponibles.

Comme mentionné krusty.ar somelist.lastest apparemment aussi.

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
la source
1
problème avec cela, c'est que vous devez savoir s'il s'agit d'une barre oblique inverse ou d'une barre oblique inverse
Joseph Le Brech
4

Notez que les guillemets doubles échappent aux chaînes.

'C:\projects\blah.dll'.split('\\').last
krusty.ar
la source
5
Le traiter uniquement comme une chaîne, plutôt que comme un chemin, rend le code moins portable.
Boatcoder
Ceci est bien plus complexe que nécessaire et est spécifique à Windows. Tu peux juste File.basename. Et, comme certaines des autres réponses, ne répond pas à la question du PO.
Keith Bennett
0

Si vous avez accès aux variables ENV, scancombinées à ce petit regex (qui trouve le dernier mot mais un, un point, puis le dernier mot de la chaîne) mettra le nom du fichier dans 'nom de fichier':

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

De toute évidence, vous pouvez utiliser scanet l'expression régulière sur n'importe quel nom de chemin qui inclut le nom de fichier, et __FILE__c'est le choix évident:

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

Vous pouvez obtenir le chemin du répertoire du script actuel avec:

File.dirname __FILE__
Smar
la source
La question ne portait pas sur le chemin, mais sur le nom du fichier . "Comment puis-je obtenir le nom de fichier à partir d'un chemin de fichier dans Ruby?"
fontno
Ce serait:File.basename __FILE__
Samuel