Board logo

标题: [问题求助] 包含需要转义才能被PowerShell处理的字符串,能否自动添加转义字符? [打印本页]

作者: 化璟钰    时间: 2024-4-15 15:29     标题: 包含需要转义才能被PowerShell处理的字符串,能否自动添加转义字符?

我在处理不同位置的相同文件时,需要把文件转为相对路径,使用 Resolve-Path cmdlet。
但我发现 Resolve-Path -Relative 处理后,部分文件无法被找到。
仔细研究后,发现这些未找到的文件,文件名都含有特殊字符(比如“[”)。用 Tab 键自动填充时,会在这些特殊字符前自动加“`”符号。所以是 Resolve-Path 输出的相对路径的字符串没有转义字符导致无法正确找到这些文件。

假设有这些文件:
  1. C:\Test\1.txt
  2. C:\Test\2.txt
  3. C:\Test\1[2].txt
  4. C:\Test\backup\1.txt
复制代码
  1. D:\Test\1.txt
  2. D:\Test\2.txt
  3. D:\Test\1[2].txt
  4. D:\Test\backup\1.txt
复制代码
当前目录在 C:\Test,我要根据 C:\Test 下拥有的文件来列出 D:\Test 中存在的相同文件(包括无限层级的子文件夹)。
首先我先将文件的相对路径保存到 $temp 变量。
  1. $temp=((Get-ChildItem -Recurse -Force "C:\Test" ).FullName |Resolve-Path -Relative)
复制代码
然后切换当前目录到 D:\Test。(内容基本相同。)
  1. Set-Location D:\Test
复制代码
然后通过管道来列出之前保存在 $temp 相对路径对应的文件。
  1. $temp|Get-Item -Force
复制代码
这时发现少输出少了一行,D:\Test\backup\1[2].txt 没能列出。很可能是因为转义字符导致的问题。但也没有报错。

更简单的例子:
假设有两个文件:
  1. C:\Test2\1.txt
  2. C:\Test2\1[2].txt
复制代码
然后执行以下两条命令(不需要指定当前目录):
  1. (Get-Item "C:\Test2\1.txt").FullName|Get-Item -Force
  2. (Get-Item "C:\Test2\1[2].txt").FullName|Get-Item -Force
复制代码
前者可以输出文件信息,但是后者则是没有输出。

因此我想了解是否有函数能对字符串或路径添加转义字符,或者是有没有办法能让 Resolve-Path 以文本外的其它类型输出内容等的方式来解决问题。还是说只能手动写程序来查找这些需要转义的字符并为这些字符添加转义字符。
作者: Five66    时间: 2024-4-15 17:21

不想路径某些字符被解析为正则就使用 -LiteralPath 选项
不想路径某些字符被解析为变量就用英文单引号引起来
例如:
  1. (Get-Item -LiteralPath 'C:\Test2\1[2].txt').FullName|foreach-object{Resolve-Path -Relative -LiteralPath $_}
复制代码

作者: 化璟钰    时间: 2024-4-15 22:24

本帖最后由 化璟钰 于 2024-4-15 22:31 编辑

回复 2# Five66
感谢。我参考你给出的信息,基本解决了。你指出了我未注意到的地方。(“$”符号。)
我将按变量中的相对路径来 Get-Item 的命令修改成了
  1. $temp|ForEach-Object{Get-Item -Force -LiteralPath $_}
复制代码

另外,我似乎发现了 Bug。当当前文件夹的完整路径包含“[”或"]"时,用 Get-Item -LiteralPath 并在后面输入文件名,(仅限 Get-Item)执行会报错,提示找不到文件。但是当当前文件夹不包含这些符号时,不影响列出当前文件夹下的文件或文件夹或无限层级子文件夹下的文件或文件夹中包含这些符号的项目。
以及在包含这两个符号之一的文件夹中用文件资源管理器打开 PowerShell 终端,或是在命令提示符当前位置包含这两个符号之一时的中打开 PowerShell,都会回到 C:\。(或是相对于某个位置的驱动器根目录。我没有其它驱动器。)
作者: Five66    时间: 2024-4-16 00:01

Get-Item是这样的 , 使用完整路径就行了 , 实在不行就用script方式的
例如:
  1. Get-Item -LiteralPath ($pwd.path+'\pp[1].txt')
  2. #注意$pwd的值
  3. #=======
  4. [io.fileinfo]'pp[1].txt'
  5. #注意判断结果
复制代码
至于用文件资源管理器打开 PowerShell 终端会回到 C:\ , win7跟win8是这样的 , 无解 ,  win8.1是没问题的 , 其他版本的系统不清楚
作者: 化璟钰    时间: 2024-4-16 04:21

回复 4# Five66
看来也只能按需要转换完整路径了。
我用的是 Windows 11 22H2。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2