Пробелы в именах файлов с использованием forfiles и 7zip - PullRequest
4 голосов
/ 25 мая 2011

Я пишу скрипт для архивирования старых файлов, используя forfiles для циклического воспроизведения и 7za для архивирования. Я боролся с тем, как бороться с пробелами в именах файлов, и, хотя я нашел решение, которое, кажется, работает, не понимая, почему я нервничаю по поводу его развертывания в производстве.

Вот команда, которая работает:

forfiles -p%rootLogDir% -s -m*.log -d-14 -c"cmd /c 7za a -tzip """@PATH\@FILE-%date%.zip""" """@PATH\@FILE""""

Обратите внимание, что аргументы пути и имени файла для 7za содержат 3 (да ТРИ) набора кавычек вокруг них. Один набор кавычек ничего не делает, два набора кавычек привели к тому, что скрипт добавил каждый файл в каталоге в архив, а не указанный, и три, похоже, работают.

Может кто-нибудь объяснить, почему так много требуется? Я бы подумал, что после одного сета остальные излишни, но, видимо, я ошибаюсь.

Ответы [ 3 ]

2 голосов
/ 27 мая 2011

(forfiles является подкомандой cmd.exe? Если это так, вам следует пометить свой вопрос одним из множества доступных (MS) оконных тегов.)

Цитирование может быть невыносимым,даже для людей, имеющих большой опыт в написании сценариев shell и bat.

@ msg BugFinder подходит, и я бы добавил, что 3 dbl-кавычки - это один из способов "заключить в кавычки" один символ двойной кавычки.

Вы работаете «с» командным процессором (cmd.exe?).Вы вводите команду (с 1 или более словами или операторами), например,

myCommand /s /d %dir% file1 file2 > sumFile

, а затем нажимаете клавишу ввода.Командный процессор не просто начинает выполнять команду, которую вы отправили, он сканирует строку, ища слова и символы особого случая, например имена переменных.В оболочках Unix переменные среды выглядят как $varName или ${varName}.В .bat файлах %var% или %%v%%.Эта переменная должна быть преобразована в значение.

Это только один проход, который делает командный процессор, есть и другие.Но для ваших нужд cmd-процессор сканирует наборы слов, которые должны восприниматься как одно слово.Если у вас есть var="one two", то, не заключая значение в кавычки, запутает любую команду, которая должна его обработать.это будет выглядеть как var=one .... two (отдельное слово, верно?).

Так что, если по какой-то причине вам нужно передать символ двойной кавычки на нижний уровень обработки, вы должны следовать командному процессоруправила, цитируйте вещи по мере необходимости, и тогда все будет работать хорошо.

Так же, как «слово» - это слово в кавычках, """ - это двойная кавычка в кавычках.После того, как командный процессор выполнит обычную обработку кавычек, средняя двойная кавычка все еще останется в «представлении» командного процессора о том, что находится в командной строке (после того, как переменная была расширена, а все остальные порядки правил обработки былиа затем.)

Вот так!

Итак, чтобы подвести итог, вы написали в комментарии

Но тогда """ -> "" -> ",

Нет, """ => "

так почему одной цитаты недостаточно?

Поскольку использование """ - это один из способов заставить командный процессор оставить автономную двойную кавычку в командной строке и не взрываться.

Илиполучает ли первая сжатая двойная кавычка какую-то магическую силу?

Никаких магических сил, обратите внимание, что ваша команда имеет более поздние значения """ с.Каждый набор оставляет 1 " char для последующей обработки.

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

Наконец, за отличное напоминание, написанное belisarius,

Позвольте мне поприветствовать вас в StackOverflow и напомнить три вещи, которые мы обычно делаем здесь: 1) Как только вы получаете помощьпопробуйте дать это тоже, отвечая на вопросы в вашей области знаний 2) Прочитайте часто задаваемые вопросы, http://tinyurl.com/2vycnvr, 3) Когда вы видите хорошие вопросы и ответы, оцените их, используя серые треугольники, http://i.stack.imgur.com/kygEP.png, поскольку доверие к системе основано на репутации, которую пользователи получают, делясь своими знаниями.Также не забудьте принять ответ, который лучше решит вашу проблему, если таковой имеется, нажав знак галочки, http://i.stack.imgur.com/uqJeW.png

Надеюсь, это поможет.

1 голос
/ 25 мая 2011

При быстром угадывании, например, "" "=", например, 2 кавычки вокруг кавычки .. a \ "также может быть достаточно.

0 голосов
/ 26 апреля 2019

Все имена файлов и пути, содержащие пробелы, должны быть заключены в кавычки.

Далее, относительно вашего вопроса, как насчет указания пути, например:

start /max /d"C:\Program files\foo\" ba.exe -somearguments
...