Как удалить все символы после последнего обратного слеша в пути с помощью Batch - PullRequest
1 голос
/ 07 июня 2019

РЕДАКТИРОВАТЬ: значение %%a равно

<MachineEntry uuid="{awae1979-6512-4br8-acg5-3oe94f56712de}" src="C:\Users\John\VirtualBox VMs\VM\VM.vbox"/>

Я пытаюсь получить папку на виртуальной машине VMWare.Поскольку пользователь может изменить местоположение папки, путь никогда не будет одинаковым.Я создал скрипт, который захватывает путь для любых виртуальных машин в системе, но проблема в том, что у меня есть путь, который заканчивается в файле.В приведенном мною коде я пытался использовать существующий цикл findstr для удаления косой черты и конечных символов, но он удаляет только C:\.Вот пример моего текущего кода:

(FOR /F "delims=" %%a in ('findstr /I /L "src" VirtualBox.xml') DO (
   SET "line=%%a"
   REM This is the term that the script searches for
   SET "line=!line:*src=!"
   REM This removes the excess characters from the grabbed string
   SET "line=!line:~2,-3!"
   SET "line=!line:*\=!"
   FOR /F "delims=<" %%b in ("!line!") DO ECHO !line!
))
PAUSE

В моем примере кода он поставляет Users\John\VirtualBox VMs\VM\VM.vbox.В итоге получается только отрезать C:\.Я хочу, чтобы вместо этого он отрезал последний \, давая мне C:\Users\John\VirtualBox VMs\VM.Любые идеи о том, как я мог бы заставить код повторяться с конца строки, а не с самого начала?Любые советы или предложения приветствуются!

Ответы [ 3 ]

3 голосов
/ 07 июня 2019

Не проще ли использовать двойные кавычки в качестве разделителей?

@For /F Tokens^=4Delims^=^" %%A In ('Find "src="^<"VirtualBox.xml"')Do @Echo(%%A

или, если вам нужен только путь, а не полная строка:

@For /F Tokens^=4Delims^=^" %%A In ('Find "src="^<"VirtualBox.xml"')Do @Echo(%%~dpA

[Edit /]

Вот альтернативное решение , основанное на расположении, предоставленном LotPings, в их комментариях ниже, и использующее :

@For /F "Delims=" %%A In ('PowerShell -NoProfile -Command^
 "[XML]$VBoxes = Get-Content "$Env:UserProfile\.VirtualBox\VirtualBox.xml";"
 "$VBoxes.VirtualBox.Global.MachineRegistry.MachineEntry |"
 "ForEach-Object {Split-Path -Path "$_.src" -Resolve}" 2^>Nul'
)Do @Echo(%%A

Это однострочная команда, измененная на многострочную для улучшения читабельности.В нем я использовал Split-Path вместе с -Resolve, чтобы выводились только те результаты, которые доступны в данный момент.

2 голосов
/ 07 июня 2019

Вы можете использовать = и / в качестве разделителей для извлечения указанного в кавычках пути, а затем позволить модификаторам ~ делать свою работу:

for /F "tokens=3 delims==/" %%L in ('findstr /I "src=" "VirtualBox.xml"') do (
    echo Full path: %%~L
    echo File name: %%~nxL
    echo Dir. path: %%~dpL
)
1 голос
/ 08 июня 2019

Мое решение использует в пакетном файле:

@echo off
for /F "tokens=3 delims=/=" %%I in ('%SystemRoot%\System32\findstr.exe /I /L "src" VirtualBox.xml') do set "VirtualBoxPath=%%~dpI"
echo Virtual box path is: "%VirtualBoxPath%"

FOR с параметром /F, в этом случае запускается новый командный процесс в фоновом режиме с %ComSpec% /c и командной строкоймежду двумя ' внутри круглых скобок, в результате чего Windows установлена ​​в C:\Windows при выполнении:

C:\Windows\System32\cmd.exe /c C:\Windows\System32\findstr.exe /I /L "src" VirtualBox.xml

FINDSTR поиск без учета регистра строк, содержащих буквенную строку src в файле VirtualBox.xml в текущем каталоге, который также может быть каталогом, отличным от каталога, содержащего пакетный файл.В этом случае FINDSTR выводит для обработки STDOUT фоновой команды, обрабатывающей строку:

<MachineEntry uuid="{awae1979-6512-4br8-acg5-3oe94f56712de}" src="C:\Users\John\VirtualBox VMs\VM\VM.vbox"/>

FOR захватывает все выходные данные для обработки STDOUT запущенного командного процесса и обрабатывает захваченный текст построчно после того, как запущенный cmd.exe завершился сам.

FOR игнорирует всегда пустые строки при обработке захваченного вывода.

FOR по умолчанию разделяет каждую строку на подстроки, используя обычный пробел и горизонтальную табуляцию в качестве разделителей, и назначает только первую строку с пробелом / символ табуляции с разделителями для указанной переменной цикла I.Поведение разделения строки изменено для этой задачи путем указания tokens=3 delims=/= в FOR командной строке после опции /F.

Разделителями строк теперь являются косая черта / и равныезнак =, означающий, что строка XML для обработки разбивается на:

  1. <MachineEntry uuid
  2. "{awae1979-6512-4br8-acg5-3oe94f56712de}" src
  3. "C:\Users\John\VirtualBox VMs\VM\VM.vbox"
  4. >

Интересна только третья строка, которая назначается переменной цикла I из-за tokens=3.
Таким образом, переменной цикла I присваивается строка:

"C:\Users\John\VirtualBox VMs\VM\VM.vbox"

FOR по умолчанию игнорирует также все строки, начинающиеся с точки с запятой, поскольку eol=; является значением по умолчанию для конца строки.Параметр конца строки не должен изменяться здесь, потому что обрабатываемая строка XML никогда не начинается с ;.

В действительности FOR сначала разбивает строку, используя указанную строку или строку по умолчаниюразделители, а затем проверяет, начинается ли первая подстрока с заданным символом или символом конца строки по умолчанию.Так что FOR также будет игнорировать в этом случае строку, начинающуюся, например, с =/; из-за = и /, будет удалена во время разбиения строки, а затем первая подстрока начинается с ;, хотя строкасамо начинается с =, и по этой причине строка полностью игнорируется, хотя назначенная переменной цикла I должна быть третьей, а не первой подстрокой.

Ссылка на строку, назначенную переменной цикла Iс %%~dp с использованием трех модификаторов:

  • Первый - ~, что приводит к удалению окружающего " из строки, присвоенной переменной цикла I.
  • Второйодин - d, что означает букву диска с двоеточием.
  • Третий - p, что означает путь без буквы диска и двоеточия.
    Путь - это все до последней обратной косой черты, включая последнюю обратную косую черту..

Поэтому строка C:\Users\John\VirtualBox VMs\VM\ присваивается переменной среды VirtualBoxPath.

В общем случае она не соответствуеттер при применении модификаторов к строке, назначенной переменной цикла, если эта строка действительно ссылается на существующий файл или папку.Модификаторы применяются к самой строке, если файл / папка не может быть найден FOR со строкой, присвоенной ссылочной переменной цикла в файловой системе.Конечно, файл / папка, на которую ссылается строка, назначенная переменной цикла, должен существовать, если он неполный, например, просто имя файла без расширения файла назначено переменной цикла и требуется диск, путь или расширение файла.В этом случае FOR получает доступ к файловой системе, чтобы получить полное имя файла с неполной строкой имени файла, и старается получить необходимые данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...