Как обрабатывать имена файлов с пробелами? - PullRequest
8 голосов
/ 26 ноября 2010

Я использую Perl на Windows (Active Perl).У меня есть Perl-программа для перетаскивания файлов в текущей папке и объединения их всех с помощью команды dos copy, вызываемой изнутри с помощью system () ...

Когда я выполняюсь, это выдает ошибку dos, говорящую «Системане могу найти указанный файл. "Это связано с пробелами в именах файлов, которые у меня есть.

Это код 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 возвращает массив имен файлов в моей текущей папке. Эти имена файлов имеют пробелы вмежду ними, поэтому элементы массива имеют пробелы между ними.Когда я использую систему (...) для выполнения команды копирования этих элементов массива, используя "$ _", как показано выше, выдается ошибка, как указано выше.

Я пробовал несколько способов, которыми я мог бы вызватьсистема (...), но безуспешно.

Я хотел бы знать,

1] Как я могу получить эту работу с файлами, между которыми есть пробелы, используя приведенный выше код,Как «экранировать» пробел в именах файлов.

2] Любое альтернативное решение в Perl для достижения того же.(Простые приветствуются ..)

Ответы [ 6 ]

11 голосов
/ 26 ноября 2010

Прекратите использовать system(), чтобы сделать вызов, который можно сделать с помощью переносимой библиотеки.В Perl есть модуль File :: Copy , используйте его вместо этого, и вам не придется беспокоиться о таких вещах, плюс вы получите гораздо лучшую переносимость ОС.

9 голосов
/ 26 ноября 2010

Ваш код не добавляет кавычки вокруг имен файлов.

Попробуйте

"\"$_\""

и

"\"$outfile\""
7 голосов
/ 26 ноября 2010

system редко правильный ответ, use <a href="http://search.cpan.org/perldoc?File%3a%3aCopy">File::Copy</a>;

Чтобы объединить все файлы:

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;
1 голос
/ 26 ноября 2010

Проблемы могут возникнуть при попытке доступа к переменной $_ внутри внутреннего блока.Самый безопасный способ, измените:

foreach (@files)

на:

foreach $file (@files)

Затем внесите необходимые изменения в @args и не используйте двойные кавычки, чтобы включить их в строку.

@args = ('copy' ,"/b ","\"$file\"","+","$outfile", "$outfile");
...
@args = ('copy' ,"/b ","$outfile","+","\"$file\"", "$outfile");
1 голос
/ 26 ноября 2010

В Windows вы можете обычно ставить двойные кавычки вокруг имен файлов (и / или путей), позволяя использовать специальные символы, например "длинные имена файлов".

C: \ "мой длинный путь \ это файл.mp3"

Редактировать:

Разве это не работает?

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

(ПРИМЕЧАНИЕ. ДВОЙНЫЕ кавычки в строке, а не одинарные кавычки)

0 голосов
/ 28 февраля 2017

$ filename = ~ s / \ / \ /;

какое бы ни было имя файла, просто используйте косую черту для ссылки на пробелы

...