如何在WMIC的WHERE子句中同时转义逗号和右括号?

3

我正在尝试以与本地语言无关的方式检索文件的修改日期,使用以下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\"^" (这会因为 , 而失败)
对使用 \ 转义 , 和/或 ) 的尝试也没有起作用;

*) 这些是我不喜欢的尝试,因为没有使用 "" 来包含文件路径,这可能会导致分隔符 (SPACETAB;=,) 或特殊字符(如 ^&())出现问题。

那么有没有办法允许 wmic 查询中文件路径中的 ,) 字符,使其不会失败?是否有特殊的字符(序列)来转义逗号或右括号?或者也许有另一种方法可以解决这个问题,使用不同类型的查询或 WHERE 子句?


有一个类似的问题:How do I escape comma in WMIC inside like string;但它只涉及转义 ,,并没有完全阐述如何转义 )。这就是为什么我在问...

3个回答

2
以下方法允许文件路径中包含逗号,但是如果出现右括号)则会失败:
==> 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

编辑。以下示例是根据 @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

==>

我可以确认,与“下面的方法允许文件路径中包含逗号”相反,该方法——wmic DataFile WHERE (Name = "D:\\bat\\Unusual Names\\2c,comma.txt") get Name, LastModified——如果目录名中有一个或多个逗号,则无法正常工作。(例如,wmic DataFile WHERE (Name = "D:\\a\\Unusual\\2c, Names\\comma.txt") get LastModified - Rublacava
也许是因为它将"Unusual \ 2c,Names"解释为"2c, Names"是"Unusual"的子目录(而不是一个目录,正如它应该解释的那样 - "Unusual,Names")。 如果逗号所在的目录是当前目录的父目录,则`set“ olddirname = dirname2keep”&& set“ newdirname = nocommadirname”&& cd .. && rename“%olddirname%”“%newdirname%” && cd%newdirname%&& wmic DataFile WHERE(Name =“ D:\ a \%newdirname%\comma.txt”)get LastModifiedtimeout 2 && cd .. && rename“%newdirname%”“%olddirname%”`有效(在"LastModified"和"timeout"之间具有两个换行符)。 - Rublacava
@Rublacava 抱歉,我不明白,但请查看更新后的答案。 - JosefZ
@ JosefZ - 我在详细说明你的方法无法处理包含一个或多个逗号的目录名称,例如 "D:\dir\directory\sub,directory\filename.txt"。 - Rublacava

1

同时我自己找到了一个(不幸的是不太全面的)解决方案,它依赖于目标磁盘驱动器上启用了8.3文件名,因为对于包含逗号的文件名,会生成一个不带,的短文件名,因此我只需要考虑右括号)。例如,长文件路径:

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

变成了一个短的,像这样:

"D:\TESTIN~1\(SH)F_~1.txt"
为了检索短文件名,使用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

1
解决方案:

D:\>mklink /H "1.jpg" "D:\p\a\t\h\fi,le.jpg"
Hardlink created for 1.jpg <<===>> D:\p\a\t\h\fi,le.jpg

D:\>wmic datafile where Name="D:\\1.jpg" list /format:list

我理解不想重命名文件,查看其元数据,然后将其重命名回原始文件名的想法。我重新尝试了@JosefZ的解决方案,但它们没有起作用。我还尝试了JosefZ的PowerShell解决方案,但也没有起作用。在cmd中运行dir/x时,Windows 10未显示NTFS外部硬盘驱动器中文件的8.3文件名。(Windows 7显示这样的文件名,并且运行fsutil behavior set disable8dot3 0也无法修复Windows 10的问题。)这不是一个完美的解决方案,因为wmic不是一个完美的程序。同样遇到逗号转义问题的用户可以参考:使用wmic时转义字符串

不错的解决方案!当启用8.3文件名时,已经存在的文件不会获得短文件名,只有对新文件(或重命名的文件)生成这样的短名称。 - aschipfl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接