Как обрабатывать имена файлов с пробелами?

Я использую Perl на окнах (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 ответов

Решение

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

Пытаться

"\"$_\""

а также

"\"$outfile\""

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

system редко правильный ответ, use File::Copy;

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

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;

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

foreach (@files)

чтобы:

foreach $file (@files)

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

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

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

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

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

Это не работает?

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

(ЗАМЕТЬТЕ ДВОЙНЫЕ кавычки внутри строки, а не одиночные кавычки)

Встроенная команда "переименовать" также перемещает файлы:

    rename $source, $destination;   # ...and move

Я использую это на окнах все время.

$filename =~ s/\ /\ /;

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

Другие вопросы по тегам