2010-08-18 12 views
14
$a = '/etc/init/tree/errrocodr/a.txt' 

Voglio estrarre /etc/init/tree/errrocodr/-$dir e a.txt-$file. Come lo posso fare?Come posso separare un percorso completo in directory e nome file?

(NdR: la domanda originale presume che avevi bisogno di un espressione regolare per questo.)

+0

Non hai già fatto questa domanda a http://stackoverflow.com/questions/3511214/how-to-support-the-searching-file-based-on-regular-expression? Dovresti modificare la domanda originale per chiarirla, piuttosto che pubblicarne una nuova. – Ether

+0

@Ether, questa è una domanda totalmente diversa, che chiede come ottenere un elenco di file basato su un carattere jolly. Questo è più come dividere un singolo filepec nelle sue parti. – paxdiablo

risposta

24

Basta usare Basename:

use File::Basename; 
$fullspec = "/etc/init/tree/errrocodr/a.txt"; 

my($file, $dir, $ext) = fileparse($fullspec); 
print "Directory: " . $dir . "\n"; 
print "File:  " . $file . "\n"; 
print "Suffix: " . $ext . "\n\n"; 

my($file, $dir, $ext) = fileparse($fullspec, qr/\.[^.]*/); 
print "Directory: " . $dir . "\n"; 
print "File:  " . $file . "\n"; 
print "Suffix: " . $ext . "\n"; 

si può vedere questo ritorno i risultati richiesti, ma è anche in grado di catturare le estensioni (nell'ultima sezione sopra):

Directory: /etc/init/tree/errrocodr/ 
File:  a.txt 
Suffix: 

Directory: /etc/init/tree/errrocodr/ 
File:  a 
Suffix: .txt 
+2

In alternativa, dai un'occhiata a File :: Spec-> splitpath(), che separa anche il volume (se ti capita di trovarti su una piattaforma che ha una cosa del genere). Il vantaggio di entrambi i pacchetti è che sono standard e portatili. –

16

non hai bisogno di una regex per questo, è possibile utilizzare dirname():

use File::Basename; 
my $dir = dirname($a) 

tuttavia questo regex funzionerà:

my $dir = $a 
$dir =~ s/(.*)\/.*$/$1/ 
+0

+1, ma IMHO non dovrebbe usare la variabile '$ a' nel tuo esempio anche se l'OP ha erroneamente fatto. È usato per 'sort' – dawg

0

Ad esempio:

$a =~ m#^(.*?)([^/]*)$#; 
    ($dir,$file) = ($1,$2); 

Ma, come altro sa id, è meglio usare solo Basename per questo.

E, BTW, meglio evitare $a e $b come nomi di variabili, in quanto hanno un significato speciale, per la funzione sort.

1

Penso che una soluzione regex sia un'esigenza perfettamente legittima, dal momento che il mio googling per esattamente questo mi ha portato qui. Voglio estrarre un nome di file in un gruppo che fa parte di un'espressione di corrispondenza più grande - ecco il mio tentativo:

~> echo "https://stackoverflow.com/a/b/c/d" | perl -ne '/(?<dir>\/(\w+\/)*)(?<file>\w+)/ && print "dir $+{dir} file $+{file}\n";' 
dir /a/b/c/ file d 
0

provare questo; funziona almeno per il nome del file, ma quando lo modifichi, ti dà anche la direzione: Puoi anche modificarlo su sistemi UNIX per il \ invece se/o per usarli entrambi con |

$ nomefile = ~ s /(^.*/)// g;

in qualche modo il backslash prima del 2 °/non viene visualizzato ...

1

Usa @array = split("/", $a); e quindi $array[-1] è il nome del file.

Problemi correlati