2010-11-26 16 views
8

J'utilise Perl sur windows (Active Perl). J'ai un programme Perl pour regrouper les fichiers dans le dossier actuel, et les concaténer tous en utilisant la commande DOS Copy appelée de l'intérieur using system() ...Comment gérer les noms de fichiers avec des espaces?

Lorsque j'exécute, cela donne une erreur de dos disant "Le système ne peut pas trouver le fichier spécifié. " C'est lié aux espaces dans les noms de fichiers que j'ai.

Voici le code perl: -

@files = glob "*.mp3"; 
$outfile = 'final.mp3'; 
$firsttime = 1; 
foreach (@files) 
{ 

    if($firsttime == 1) 
    { 
     @args = ('copy' ,"/b ","$_","+","$outfile", "$outfile"); 
     system (@args); 
     #system("copy /b '$_'+$outfile $outfile"); 
     $firsttime = 0; 
    } 
    else 
    { 
     @args = ('copy' ,"/b ","$outfile","+","$_", "$outfile"); 
     system (@args); 
     #system("copy /b $outfile+'$_' $outfile"); 
    } 

} 

glob retourne un tableau de noms de fichiers dans mon dossier en cours, ces noms de fichiers ont des espaces entre eux, de sorte que les éléments du tableau ont des espaces entre les deux. Lorsque j'utilise le système (...) pour exécuter ma commande de copie sur ces éléments de tableau en utilisant "$ _" comme indiqué ci-dessus, cela donne une erreur comme ci-dessus.

J'ai essayé plusieurs façons d'appeler le système (...) mais sans succès.

Je voudrais savoir,

1] Comment puis-je obtenir ce travail sur les fichiers qui ont des espaces entre eux en utilisant le code ci-dessus. Comment "échapper" l'espace blanc dans les noms de fichiers.

2] Toute solution alternative en Perl pour atteindre la même chose. (Les simples sont les bienvenus ..)

+0

Pourquoi ne vous contentez pas de lire les fichiers et les imprimer dans un fichier de sortie? – robert

+0

@robert: Signification open(), read() et write() l'une après l'autre. – goldenmean

+0

Aucune raison pour laquelle cette question n'a jamais reçu de révision. +1 de moi. Ran dans le même problème (encore) ...: -/... juste maintenant. – 0xC0000022L

Répondre

9

Votre code n'ajoute aucun guillemet autour des noms de fichiers.

Essayez

"\"$_\"" 

et

"\"$outfile\"" 
+0

@Ed - Merci. Soln rapide, précis et efficace. Love perl .. – goldenmean

1

problèmes peuvent survenir lorsque vous essayez d'accéder à la $_ variable à l'intérieur d'un bloc interne. Le moyen le plus sûr, le changement:

foreach (@files) 

à:

foreach $file (@files) 

Puis faites les changements nécessaires sur @args, et échapper à doublequotes de les inclure dans la chaîne ..

@args = ('copy' ,"/b ","\"$file\"","+","$outfile", "$outfile"); 
... 
@args = ('copy' ,"/b ","$outfile","+","\"$file\"", "$outfile"); 
1

Dans les fenêtres vous pouvez normalement placer des guillemets autour des noms de fichiers (et/ou des chemins) permettant des caractères spéciaux, par exemple des "noms de fichiers longs".

C: \ "mon long chemin \ c'est un file.mp3"

Edit:

Est-ce fonctionne pas?

system("copy /b \"$_\"+$outfile $outfile"); 

(notez les guillemets doubles dans la chaîne non simples citations)

+0

@Viper_Sb: Je sais, mais comment obtenir cet effet dans le script perl est la question. – goldenmean

+0

@goldenmean a édité ma réponse –

+0

@Viper_sb: merci, oui c'est comme ça. travaux. – goldenmean

11

Cessez d'utiliser system() pour faire un appel qui peut être fait avec une bibliothèque portable. Perl a un module File::Copy, utilisez-le à la place et vous n'avez pas à vous soucier de choses comme celles-ci et vous obtenez une bien meilleure portabilité du système d'exploitation.

+2

et une meilleure détection/gestion des erreurs – ysth

+0

Merci pour cette approche différente en utilisant File :: Copy. – goldenmean

7

system est rarement la bonne réponse, use File::Copy ;

concaténer tous les fichiers:

use File::Copy; 
my @in = glob "*.mp3"; 
my $out = "final.mp3"; 

open my $outh, ">", $out; 
for my $file (@in) { 
    next if $file eq $out; 
    copy($file, $outh); 
} 
close $outh; 
+0

@Gravity: Merci pour le code snipped montrant l'utilisation de File :: Copy. – goldenmean

0

$ filename = ~ s/\/\ /;

Quel que soit le nom de fichier est d'utiliser juste barre oblique pour espaces refrence