Не работает обрезка левой строки в пакетном файле

#batch-file

#пакетный файл

Вопрос:

огромный новичок. У меня есть два пакетных файла, которые работают, но когда я пытаюсь объединить их, это не удается.

Первый пакетный файл выполняет поиск в каталоге и копирует имена файлов в качестве переменной…

 @echo off
setlocal disableDelayedExpansion
cd I:TestBatchesNew folder (2)New folder
set "files="
for /r %%F in (*) do call set files=%%files%% "%%F"
echo %files% | clip
  

В моем случае в папке есть один файл, и он копирует

«I:TestBatchesNew папка (2) New folderFotolia_93178533_Subscription_Monthly_M.jpg »

в буфер обмена

Второй пакетный файл предназначен для обрезки левой переменной всего до четырех символов слева. Это работает само по себе.

 set str=politic
echo.%str%
set str=%str:~0,4%
echo.%str%
  

Но когда я пытаюсь объединить два, это не работает. В буфер обмена ничего не записывается.

 @echo off
setlocal disableDelayedExpansion
cd I:TestBatchesNew folder (2)New folder
set "files="
for /r %%F in (*) do call set files=%%files%% "%%F"
echo %files%
set files=%files:~0,4%
echo %files% | clip
  

В чем ошибка? Спасибо, Джеймс

Комментарии:

1. пожалуйста, объясните, каким должен быть ваш ожидаемый вывод и конечный результат. Вы знаете, что %%F будет полным путем, не так ли?. Это означает, что %files% будет, вероятно, чрезвычайно длинным однострочным списком рекурсивных файлов filepath, который быстро достигнет предела, а использование первых четырех символов первого полного пути не приведет к достижению того, что, по вашему мнению, вам нужно.

2. @Compo все, что вы говорите, верно, но, насколько нам известно, OP, возможно, просто экспериментирует на данном этапе, и он говорит, что в for команде получен только один файл, поэтому его переменная не переполнится, но она по-прежнему не возвращает ожидаемый результат первых четырех символов (одного-единственного) пути. (На самом деле первыми двумя символами должны быть пробел и кавычка, но по какой-то причине они даже не возвращаются.)

3. Еще раз привет, спасибо за ответы. Наша система настроена так, что в проверяемой папке всегда будет только один файл. Таким образом, переменные files по сути должны быть текстовой строкой, которую я затем хочу обрезать, а затем скопировать в буфер обмена. Я могу заставить имя файла отображаться в буфере обмена (на самом деле в нем есть пробел, затем речевые обозначения, а затем имя файла) Но когда я пытаюсь обрезать, используя set files =% files: ~ 0,4%, все идет не так.

4. Это правильная обрезка.

5. Если бы существовал только один файл, то вы бы не [ 1. ] использовали рекурсивный поиск в каталоге [ 2. ] вызывали переменную %files% [ 3. ] добавляли %%F к существующему содержимому %files%, предварительно убедившись, что %files% начинается с пустого файла.

Ответ №1:

Причиной проблемы является способ CMD.EXE работает с расширением переменной: оно выполняет расширение перед разбором команды. Итак, у вас есть переменная, files установленная в

«I:TestBatchesNew папка (2) New folderFotolia_93178533_Subscription_Monthly_M.jpg «

и затем команда set files=%files:~0,4% устанавливает ее в "I: значение — поэтому в ней отсутствует закрывающая кавычка.

Затем команда

 echo %files% | clip
  

на самом деле рассматривается как

 echo  "I: | clip
  

и символ канала | обрабатывается как часть (незакрытой) строки.

Я полагаю, вы, вероятно, не хотите обрезать символ кавычки, но четыре символа после него: set files=files:~2,4% должны это сделать. В противном случае включите отложенное расширение и используйте ! вместо % .

Комментарии:

1. Блестяще, в этом и заключалась проблема — удаление кавычек, окружающих %%f в конце строки 5, похоже, сработало — теперь это дает ожидаемый результат. Большое спасибо!

Ответ №2:

Вы уверены, что не хотите просто сделать это наcmd.exe подсказка?

 @For %A In ("I:TestBatchesNew folder (2)New folder*.*") Do @Echo(%~dpnA|Clip
  

или в кавычках:

 @For %A In ("I:TestBatchesNew folder (2)New folder*.*") Do @Echo("%~dpnA"|Clip
  

или даже:

 @For %A In ("I:TestBatchesNew folder (2)New folder*.*") Do @Echo(%~pnxA|Clip
  

или в кавычках:

 @For %A In ("I:TestBatchesNew folder (2)New folder*.*") Do @Echo("%~pnxA"|Clip
  

Комментарии:

1. set files=%files:~0,4% больше похоже на %~dA только. Но, возможно, я неправильно истолковал вопрос.

2. Проблема в том, что они известны без цикла, как и то, что они получают <пробел 0x20><двойная кавычка 0x22><заглавная I 0x49><двоеточие 0x3A>. Поэтому я предполагаю, что им нужен был только путь минус буква диска, т. е. » % файлов: ~ 4%

3. да, это тоже возможная интерпретация. Но set files=files:~2,4% , похоже, решает проблему (см. Ответ Klitos) — что было бы %~dA — что (как вы говорите) бессмысленно, поскольку буква диска явно определена ранее, поэтому хорошо известна.