2016-09-06 2 views
3

Я совсем не образован по кодированию, поэтому вам придется извинить любую безнадежную терминологию!Пакетный файл с пробелами в переменных/именах файлов в текстовом файле

Я выбрал несколько фрагментов кода для пакетного файла со всего Интернета (некоторые из них с этого сайта), и я попытался переписать некоторые из них в соответствии с моими потребностями.

Создает новый каталог, затем просматривает другой каталог и все его подкаталоги для имен файлов в списке .txt, а затем копирует эти файлы в каталог, созданный в начале. Любые файлы, которые не найдены в списке, записываются в другой текстовый файл, чтобы отслеживать все, что отсутствует.

Код:

md 00FoundImages 

set LIST=%cd%\imagelist.txt 
set FILESPATH=%cd%\testimages 
set DEST=%cd%\00FoundImages 

for /f "delims=" %%x in (%LIST%) do (forfiles /p %FILESPATH% /s /m %%x* /c "cmd /c move /y @path %DEST%\@file" 2>>errors.txt) 

Это прекрасно работает в большинстве условий, когда за исключением:

  1. Имя файла в текстовом файле содержит пробел
  2. Путь к каталогу в в котором находится файл партии, содержится пробел (или другой специальный символ)

Я попытался заключая в кавычки, так как:

set FILELIST="%cd%\imagelist.txt" 
set FILESPATH="%cd%\testimages" 
set DESTPATH="%cd%\00FoundImages" 

Это терпит неудачу в команде forfiles как только пространство находится в имени каталога.

Я попытался ограждающих переменную, когда он используется в кавычках, так как:

for /f "delims=" %%x in ("%LIST%") do (forfiles /p "%FILESPATH%" /s /m %%x* /c "cmd /c move /y @path "%DEST%\@file"" 2>>errors.txt) 

Когда я запустить пакетный файл из директории под названием «тестирование - Copy», я получаю сообщение об ошибке записывается в мой errors.txt файл

ERROR: Invalid argument/option - '-'. 
Type "FORFILES /?" for usage. 

Это отпечаток того, что происходит:

E:\ImageAutomationStuff\testing - Copy>md 00FoundImages 
A subdirectory or file 00FoundImages already exists. 

E:\ImageAutomationStuff\testing - Copy>set LIST=E:\ImageAutomationStuff\testing - Copy\imagelist.txt 

E:\ImageAutomationStuff\testing - Copy>set FILESPATH=E:\ImageAutomationStuff\testing - Copy\testimages 

E:\ImageAutomationStuff\testing - Copy>set DEST=E:\ImageAutomationStuff\testing - Copy\00FoundImages 

E:\ImageAutomationStuff\testing - Copy>pause 
Press any key to continue . . . 

E:\ImageAutomationStuff\testing - Copy>for /F "delims=" %x in ("E:\ImageAutomationStuff\testing - Copy\imagelist.txt") do (forfiles /p "E:\ImageAutomationStuff\testing - Copy\testimages" /s /m %x* /c "cmd /c move /y @path "E:\ImageAutomationStuff\testing - Copy\00FoundImages\@file"" 2>>errors.txt) 

E:\ImageAutomationStuff\testing - Copy>(forfiles /p "E:\ImageAutomationStuff\testing - Copy\testimages" /s /m E:\ImageAutomationStuff\testing - Copy\imagelist.txt* /c "cmd /c move /y @path "E:\ImageAutomationStuff\testing - Copy\00FoundImages\@file"" 2>>errors.txt) 

E:\ImageAutomationStuff\testing - Copy>pause 
Press any key to continue . . . 

с Рез earch Я сделал, я вижу, что вопросы такого характера очень часто спрашивают - извинения за добавление в кучу, но с моими ограниченными знаниями. Боюсь, я просто не могу решить эту проблему самостоятельно!

+0

Имена файлов (или любые другие параметры) с пробелами ДОЛЖНЫ быть заключены в кавычки. '' c: \ Program files \ Office "'. Пробелы ограничивают параметры, если только в кавычках. –

+0

Я попытался включить переменные в кавычки, но это не работает. Я сделал это несколько разных способов, включая переменные на этапе «set» и этап «for/f» – danmosa

+0

. Вы должны показать, как вы их вставляли в кавычки, редактируя свой вопрос. –

ответ

1

Чтобы избежать проблем с пробелами в дорожках и именах файлов, используйте кавычки. Но вы должны быть осторожны, когда дело доходит до forfiles, потому что все связанные с путями и файлами @ -переменные расширяются до значений, уже заключенных в "", так что это может привести к двойным кавычным значениям.

Я дал бы это попробовать:

md "%cd%\00FoundImages" 

set "LIST=%cd%\imagelist.txt" 
set "FILESPATH=%cd%\testimages" 
set "DEST=%cd%\00FoundImages" 

for /f "usebackq delims=" %%x in ("%LIST%") do (
    forfiles /p "%FILESPATH%" /s /m "%%x*" /c "cmd /c if @isdir==FALSE cd /d 0x22%DEST%0x22 & move /y @path @file" 2>>errors.txt 
) 

Что я сделал:

  • улучшенного синтаксис set так, что выражение присваивания всего заключено в ""; это позволяет избежать проблем с некоторыми специальными символами, но котировки составляют не часть значений переменных;
  • цитата %LIST%, поэтому мне пришлось добавить опцию usebackq в for /f, так как она обрабатывала значение переменной %LIST% как литеральную строку, а не файл в противном случае;
  • Путь после /p, а также образец после /m из forfiles заключены в круглые скобки; здесь очень важно, чтобы путь после /p был не, прерванный \, потому что это было бы интерпретировано как escape-символ на forfiles, чтобы избежать заключительной цитаты "; , если вы не можете заверить, что %FILESPATH% выполняет этот критерий, вместо этого напишите /p "%FILESPATH%\.";Редактировать: последнее утверждение неверно!
  • переменная @path расширяется до уже указанной строки, поэтому с ней все в порядке;
  • сложная часть - это целевой файл %DEST%\@file с вашего исходного кода, потому что @file расширяется до уже указанной строки, поэтому результатом будет что-то вроде \...\00FoundImages\"FoundImage 1.png"; поэтому цитирование всего выражения, такого как 0x22%DEST%\@file0x22 приведет к "\...\00FoundImages\"FoundImage 1.png"", поэтому имя файла FoundImage 1.png будет отображаться без кода в командном интерпретаторе; 0x22%DEST%0x22\@file - 0 0 0 0 0 Чтобы преодолеть это, просто перейдите в каталог %DEST% сначала cd /d 0x22%DEST%0x22 , поэтому он указан отдельно, затем используйте @file только для командной строки move;
  • Наконец, forfiles возвращает оба файла соответствия и, поэтому для обеспечения обработки только файлов я выполнил запрос if;

1) ... выражение 0x22 обозначает " характера в forfiles /C командных выражений и представляет свой код символа в шестнадцатеричной системе счисления; Я предпочитаю этот способ указания кавычек, потому что другой параметр, \", может повлиять на интерпретатор командной строки, поскольку он не поддерживает обратную косую черту, и поэтому он распознает метку кавычки, которая может непреднамеренно изменить ее поведение.

+0

Кажется, работает! Большое объяснение - я понимаю, что здесь происходит. Спасибо! – danmosa

0
for /f "delims=" %%x in ("%LIST%") do (forfiles /p "%FILESPATH%" /s /m %%x* /c "cmd /c move /y @path \"%DEST%\@file\"" 2>>errors.txt) 

Котировки внутри кавычек, что это команда forfiles пробеги должны быть экранированы с обратной косой черты. Но не другие цитаты, такие как стартовая папка.

+0

Это все равно производит ту же ошибку ... 'ERROR: Invalid argument/option - '-'.' ... черта, являющаяся частью имени каталога (тестирование - копирование) – danmosa

+0

Вам нужны кавычки (без обратной косой черты) вокруг '%% X' в командной строке' forfiles'. Никогда не больно вводить цитаты, даже если они не нужны. Любая строка, которая делает или может (в случае переменных) содержать пробелы, должна быть заключена в кавычки. –

+0

Использование 'for/f 'delims =" %% x in ("% LIST%") do (forfiles/p "% FILESPATH%"/s/m "%% x" */c "cmd/c move/y @path \ "% DEST% \ @ file \" "2 >> ошибки.txt) ' Результаты ' ERROR: Файлы типа "E: \ ImageAutomationStuff \ testing - Copy \ imagelist.txt *" не найден. ' – danmosa

0

Хотя я не понимаю, почему вы гнездятся FORFILES петлю в другую (FOR /F) цикл, следующий фрагмент кода следует сделать трюк:

for /f "usebackq delims=" %%x in ("%LIST%") do (
    forfiles /p "%FILESPATH%" /s /m "%%~nxx" /c "cmd /c ECHO move /y @path \"%DEST%\"\@file" 2>>errors.txt 
) 

Примечание:

  • двойные кавычки в "%FILESPATH%" и "%%~nxx";
  • сэкономленные двойные кавычки в \"%DEST%\";
  • plain @path и @file как те FORFILES переменные команды уже двойные кавычки;
  • возможно, что вам нужно переформулировать /m "%%~nxx" маску файла (я использую %%~nxx file name and extension, потому что я не знаю %LIST% содержимого файла и предположим, что список полных имен файлов);
  • важное значение: move команда всего для целей отладки; удалите предшествующий ECHO, чтобы сделать его работоспособным, не раньше, чем отлаживается.