Как обрабатывать имена файлов с пробелами?
Я использую 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/\ /\ /;
что когда-либо имя файла просто использовать косую черту для ссылки на пробелы