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

Я использую 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 для достижения того же самого. (Простые приветствуются ..)


person goldenmean    schedule 26.11.2010    source источник
comment
Почему бы вам просто не прочитать файлы и не распечатать их все в один выходной файл?   -  person robert    schedule 26.11.2010
comment
@robert: Имеются в виду open (), read () и write () один за другим ..   -  person goldenmean    schedule 26.11.2010
comment
Понятия не имею, почему этот вопрос так и не получил голосов. +1 от меня. Столкнулся с той же проблемой (снова) ...: - / ... только что.   -  person 0xC0000022L    schedule 25.11.2011


Ответы (7)


В вашем коде имена файлов не заключаются в кавычки.

Пытаться

"\"$_\""

и

"\"$outfile\""
person Ed Guiness    schedule 26.11.2010

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

person Ian C.    schedule 26.11.2010
comment
Спасибо за этот другой подход с использованием File :: Copy. - person goldenmean; 29.11.2010

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;
person user1686    schedule 26.11.2010
comment
@Gravity: Спасибо за фрагмент кода, показывающий использование File :: Copy. - person goldenmean; 29.11.2010

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

foreach (@files)

to:

foreach $file (@files)

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

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

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

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

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

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

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

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

person Viper_Sb    schedule 26.11.2010
comment
@Viper_Sb: Я знаю, но вопрос в том, как добиться такого эффекта в сценарии perl. - person goldenmean; 26.11.2010
comment
Разве это не сломается на a file "name".mp3? попробуйте \"\Q$_\E\" - person mfontani; 26.11.2010

$ filename = ~ s / \ / \ /;

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

person user3784340    schedule 28.02.2017

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

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

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

person R M    schedule 28.12.2019