【问题标题】:Copy the entire folder structure but filter subfolders based on the folder name by two different strings?复制整个文件夹结构,但通过两个不同的字符串根据文件夹名称过滤子文件夹?
【发布时间】:2021-03-19 12:27:23
【问题描述】:

如何复制整个文件夹结构,但仅根据文件夹名称通过两个不同的字符串选择一些(子)文件夹?

我试过了

PS C:\Users> $includes = "*Touch*", "*mpr*"

PS C:\Users Get-ChildItem "C:\Users\Desktop\mro" -Directory |
>>     Where-Object{$_.Name -in $includes} |
>>     Copy-Item -Destination "C:\Users\shizzle\Desktop\shi_data6" -Recurse -Force


这会保留文件夹结构,但会复制整个文件夹结构(不被包含字符串“Touch”或“mpr”的文件夹选中。

Get-ChildItem -Path 'C:\Users\Desktop\mro' | Copy-Item -Destination 'C:\Users\Desktop\shi_data9' -Recurse -Container -Filter "*Touch*"

不起作用,因为它专门通过“Touch”复制文件夹和内容,并省略了所需文件夹中的所有其他文件(不包含“Touch”)和两个-过滤器似乎也不起作用(更不用说与布尔值结合(如“Touch”或“mpr”))

【问题讨论】:

  • 也许我遗漏了什么,但这与 MATLAB 标签有什么关系?

标签: powershell get-childitem copy-item


【解决方案1】:

您正在使用-in 运算符测试名称与$includes 数组中的完全匹配,但该数组包含通配符,因此不起作用。

改为使用正则表达式 -match 运算符并将您的 $includes 变量设置为一个字符串,其中部分名称由正则表达式 OR (|) 字符分隔:

$includes = 'Touch|mpr'
Get-ChildItem "C:\Users\Desktop\shizzle\mro" -Directory |
    Where-Object{$_.Name -match $includes} |
    Copy-Item -Destination "C:\Users\shizzle\Desktop\shi_data6" -Recurse -Force

根据您的评论,通配符比较与正则表达式比较不同。

  • 在通配符比较(与运算符-likenotlike 一起使用)中,星号* 表示零或任意数量的任何字符
  • 在 Regex 中,同一个字符有不同的含义:零个或多个 PREVIOUS 字符或字符组 (见下表)
  • 比较文字文本以在数组中找到匹配的字符串,就像您尝试使用运算符-in 一样,不使用通配符或正则表达式;该字符串是否按字面意思找到。

至于代码,我已经对此进行了测试(当然使用不同的文件路径)并且工作正常,提供副本目标的文件夹已经存在。
如果不是这种情况,请以

开头的代码
if (!(Test-Path -Path "C:\Users\shizzle\Desktop\shi_data6" -PathType Container)) {
    $null = New-Item -Path "C:\Users\shizzle\Desktop\shi_data6" -ItemType Directory
}

确保首先创建它。

这是我的测试结果

源文件夹:

D:\TEST
+---DoNotCopyThisFolder
|   +---SubFolder_1
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   \---SubFolder_2
|           File_1.txt
|           File_2.txt
|           File_3.txt
|
+---mpr_Files
|   +---SubFolder_1
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   +---SubFolder_2
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   \---SubFolder_3
|           File_1.txt
|           File_2.txt
|           File_3.txt
|
+---NotThisOne
|   +---SubFolder_1
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   +---SubFolder_2
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   \---SubFolder_3
|           File_1.txt
|           File_2.txt
|           File_3.txt
|
\---Touch
    +---SubFolder_1
    |       File_1.txt
    |       File_2.txt
    |       File_3.txt
    |
    +---SubFolder_2
    |       File_1.txt
    |       File_2.txt
    |       File_3.txt
    |
    \---SubFolder_3
            File_1.txt
            File_2.txt
            File_3.txt

目标文件夹:

D:\SHI_DATA6
+---mpr_Files
|   +---SubFolder_1
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   +---SubFolder_2
|   |       File_1.txt
|   |       File_2.txt
|   |       File_3.txt
|   |
|   \---SubFolder_3
|           File_1.txt
|           File_2.txt
|           File_3.txt
|
\---Touch
    +---SubFolder_1
    |       File_1.txt
    |       File_2.txt
    |       File_3.txt
    |
    +---SubFolder_2
    |       File_1.txt
    |       File_2.txt
    |       File_3.txt
    |
    \---SubFolder_3
            File_1.txt
            File_2.txt
            File_3.txt

至于正则表达式,有几个特殊字符具有特殊含义:

正则表达式中的特殊字符

Char Description Meaning
\ Backslash Used to escape a special character
^ Caret Beginning of a string
$ Dollar sign End of a string
. Period or dot Matches any single character
| Vertical bar or pipe symbol Matches previous OR next character/group
? Question mark Match zero or one of the previous
* Asterisk or star Match zero, one or more of the previous
+ Plus sign Match one or more of the previous
( ) Opening and closing parenthesis Group characters
[ ] Opening and closing square bracket Matches a range of characters
{ } Opening and closing curly brace Matches a specified number of occurrences of the previous

【讨论】:

  • 感谢您的快速回答,但不幸的是,这不会复制任何内容。它不会抛出错误,但不会发生复制。可能因为它实际上必须是通配符,例如 'Touch*|*mpr" (这也不起作用:)
  • @pythokles 请查看我的编辑,我试图解释通配符比较与正则表达式比较之间的区别。我还展示了我的测试结果。为什么它不为您复制任何内容可能是因为在您的代码中您的原件路径错误:"C:\Users\Desktop\mro",应该是"C:\Users\shizzle\Desktop\mro"。你忘记了那里的用户名。
  • 再次感谢您的帮助。我终于明白了问题所在。它不会复制任何内容,因为我的实际文件夹结构是“C:\Users\Desktop\shizzle\mro\pre\subject_01\...”,并且正则表达式仅搜索目录中指定的文件夹。我很抱歉这个不好的例子,我不认为它会有所作为。因此,我的最后一个问题是,您是否知道一种让正则表达式搜索所有子目录并仍然通过递归保持文件夹结构的方法?
  • 如果我这样做 Get-ChildItem "C:\Users\shizzle\Downloads\copy_test\copy_test\mro" -Recurse | Where-Object{$_.Name -match $includes} | Copy-Item -Destination "C:\Users\shizzle\Downloads\test_shi10" -Recurse -Force 它又不会保留整个文件夹结构
  • 你说得对,这是我的错。我现在发布了一个新问题link,再次抱歉没有正确指定问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 2016-12-23
  • 1970-01-01
相关资源
最近更新 更多