Как избежать как запятой, так и закрывающей круглой скобки в предложении WHERE WMIC?

Я пытаюсь получить дату изменения файла независимо от локали, используя следующую команду wmic:

wmic DataFile WHERE Name="D:\\Data\\sample.txt" GET LastModified

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

Метод ниже позволяет запятые в пути к файлу, но не работает, если появляется закрывающая скобка ):

wmic DataFile WHERE (Name="D:\\Data\\sample.txt") GET LastModified

До сих пор я пробовал множество разных комбинаций, но безуспешно:

WHERE Name=D:\\Data\\sample.txt (это вообще не работает, я думаю, из-за неправильного типа данных)
WHERE Name="D:\\Data\\sample.txt" (с ошибкой ,)
WHERE Name='D:\\Data\\sample.txt' (это не с ,) *
WHERE (Name="D:\\Data\\sample.txt") (это не работает с ))
WHERE (Name='D:\\Data\\sample.txt') (это не с )) *
WHERE 'Name="D:\\Data\\sample.txt"' (это не с ,)
WHERE "Name='D:\\Data\\sample.txt'" (с ошибкой ,)
WHERE "Name=\"D:\\Data\\sample.txt\"" (это не с ,) *
WHERE ^"Name=\"D:\\Data\\sample.txt\"^" (это не работает с ,)
экранирование , и/или ) с помощью \ тоже не работает;

<суб > *) Это попытки, которые мне не нравятся, потому что не существует "", чтобы заключить путь к файлу, что может привести к проблемам с разделителями (SPACE, TAB, ;, = и ,) или специальные символы, такие как ^, &, ( и ). Суб >

Итак, есть ли способ разрешить оба символа , и ) в пути к файлу для запроса wmic не сбой? Есть ли специальный символ (последовательность) для удаления запятых или закрывающих круглых скобок? Или есть, возможно, другой метод для решения этой проблемы, с другим типом запроса или предложением WHERE?


Есть аналогичный вопрос: Как избежать запятой в WMIC внутри, как строка; но он должен избегать только , и не полностью разрабатывает также экранирование ). Вот почему я спрашиваю...

Ответ 1

  Метод ниже позволяет запятые в пути к файлу, но не удается, если появляется закрывающая скобка ):

==> wmic DataFile WHERE (Name = "D:\\bat\\Unusual Names\\2c,comma.txt") get Name, LastModified
LastModified               Name
20160513080305.362206+120  d:\bat\unusual names\2c,comma.txt

Edit. Следующий пример добавлен в ответ на комментарии @Rublacava:

==> wmic DataFile WHERE (Name = "d:\\bat\\Unusual Names\\2c, comma\\2c,comma.txt") get Name, LastModified
LastModified               Name
20160514132334.866055+120  d:\bat\unusual names\2c, comma\2c,comma.txt

Напротив, метод ниже позволяет закрывающую скобку ) в путь к файлу, но не удается, если появляется запятая ,:

==> wmic DataFile WHERE "Name = 'D:\\bat\\Unusual Names\\28(parens_29).txt'" get Name, LastModified
LastModified               Name
20160513104341.746838+120  d:\bat\unusual names\28(parens_29).txt

Не похоже, что существует общий подход для запятой , и закрывающей скобки ) вместе в пути к файлу, например. 2c,comma_28(parens_29).txt.

Однако здесь есть обходной путь с помощью PowerShell:

powershell -Command Get-WmiObject -Query """Select * from CIM_DataFile where name = 'D:\\bat\\Unusual Names\\2c,comma_28(parens_29).txt'""" ^| select name, LastModified ^| ft -AutoSize
::
::  a bit more readable
::
powershell -Command Get-WmiObject -Query """Select * from CIM_DataFile where "^
  "name = 'D:\\bat\\Unusual Names\\2c,comma_28(parens_29).txt'""" ^
  ^| select name, LastModified ^| ft -AutoSize
::
:: even more readable
::
set "_filePath=D:\bat\Unusual Names\2c,comma_28(parens_29).txt"
powershell -Command Get-WmiObject -Query ^
  """Select * from CIM_DataFile where name = '%_filePath:\=\\%'""" ^
  ^| select name, LastModified ^| ft -AutoSize

Вывод (код выше вставлен в открытое окно cmd):

==> powershell -Command Get-WmiObject -Query """Select * from CIM_DataFile where
 name = 'D:\\bat\\Unusual Names\\2c,comma_28(parens_29).txt'""" ^| select name,
LastModified ^| ft -AutoSize

name                                            LastModified
----                                            ------------
d:\bat\unusual names\2c,comma_28(parens_29).txt 20160513103717.765243+120

==> ::
==> ::  a bit more readable
==> ::
==> powershell -Command Get-WmiObject -Query """Select * from CIM_DataFile where "^
More?   "name = 'D:\\bat\\Unusual Names\\2c,comma_28(parens_29).txt'""" ^
More?   ^| select name, LastModified ^| ft -AutoSize

name                                            LastModified
----                                            ------------
d:\bat\unusual names\2c,comma_28(parens_29).txt 20160513103717.765243+120

==> ::
==> :: even more readable
==> ::
==> set "_filePath=D:\bat\Unusual Names\2c,comma_28(parens_29).txt"

==> powershell -Command Get-WmiObject -Query ^
More?   """Select * from CIM_DataFile where name = '%_filePath:\=\\%'""" ^
More?   ^| select name, LastModified ^| ft -AutoSize

name                                            LastModified
----                                            ------------
d:\bat\unusual names\2c,comma_28(parens_29).txt 20160513103717.765243+120

==>

Ответ 2

Тем временем я сам нашел (к сожалению, непонятное) решение, которое основано на том факте, что на целевом диске включено 8,3 имени файла, потому что для имени файла, содержащего запятые , генерируется короткое имя файла без, так что мне нужно только учитывать закрытие скобки ). Например, длинный путь к файлу:

"D:\Testing Data\(sh)f,n.txt"

становится коротким как:

"D:\TESTIN~1\(SH)F_~1.txt"

Чтобы получить короткое имя файла for цикла for и модификатор ~s его мета-переменной:

rem // Return full file path with only short names:
for %%F in ("D:\Testing Data\(sh)f,n.txt") do @set "FILE=%%~sfF"

wmic DataFile WHERE "EightDotThreeFileName='%FILE:\=\\%'" GET LastModified

Это даже хорошо работает со смешанным путем в качестве входных данных, что означает, что чистое имя файла короткое, но имена каталогов в родительском пути длинные (хотя это, конечно, не удастся, если родительский путь содержит , то):

rem // Return long parent path and short filename:
for %%F in ("D:\Data\(sh)f,n.txt") do @set "PPTH=%~dpF" & @set "NAME=%%~snxF"

wmic DataFile WHERE "EightDotThreeFileName='%PPTH:\=\\%%NAME%'" GET LastModified