File Powershell中的文件和文件夹操作

File Powershell中的文件和文件夹操作,file,powershell,file-management,File,Powershell,File Management,我有一个包含数千个文件名的文件夹 所有文件名都是相对于用户的userID的。某些用户在此文件夹中有多个文件,因此它会在名称的末尾附加一个数字。即susy.txt、susy1.txt、susy2.txt、carl.txt、carl1.txt等 我要做的是为每个有多个文件的用户创建一个特定的文件夹,并将所有相关文件移动到该文件夹中。所以我注意到有多个susy文档。所以我想创建一个名为Susy的文件夹,并将Susy.txt、susy1.txt和susy2.txt放入其中。。。对于所有文件,依此类推 甚

我有一个包含数千个文件名的文件夹

所有文件名都是相对于用户的userID的。某些用户在此文件夹中有多个文件,因此它会在名称的末尾附加一个数字。即susy.txt、susy1.txt、susy2.txt、carl.txt、carl1.txt等

我要做的是为每个有多个文件的用户创建一个特定的文件夹,并将所有相关文件移动到该文件夹中。所以我注意到有多个susy文档。所以我想创建一个名为Susy的文件夹,并将Susy.txt、susy1.txt和susy2.txt放入其中。。。对于所有文件,依此类推

甚至可以作为一个批处理文件来做这件事吗?如果可以的话,有人能告诉我做这件事的正确方向吗?我在编写批处理脚本方面有少量的知识,我想借此机会了解更多


谢谢

这是我刚刚捏造出来的又快又脏的解决方案。它使用正则表达式将用户名从文件名中分离出来,即该表达式将carl从carl1.txt carl3.txt carl22.txt中分离出来。然后,它根据这些名称创建文件夹,并且是唯一的。所以它只试着创造卡尔一次,而不是57次。之后,它将所有的卡尔、约翰尼和苏西等移动到新文件夹中

如果你是新来的,如果这看起来有点吓人,不要害怕。特别是正则表达式。如果你对正则表达式感到困惑的话,几乎可以肯定有一种不用它们的方法可以做到这一点,但正则表达式是一种工具,一旦你学会了它,你就会意识到它在解决问题方面有多么伟大

[regex]$pattern_name = '^\w.+?(?=[\d\.])'

# create folders for all the unique users
get-Childitem -File -path 'c:\scripts' | foreach-Object {$pattern_name.match($_).value } | sort -unique | foreach-Object { mkdir $_ }

# move files into those folders
get-Childitem -File -path 'c:\scripts' | foreach-Object {
    $user = $pattern_name.match($_).value 
    Move-Item -destination ".\$user" -Path $_.FullName
    }

这是我刚刚捏造出来的又快又脏的解决方案。它使用正则表达式将用户名从文件名中分离出来,即该表达式将carl从carl1.txt carl3.txt carl22.txt中分离出来。然后,它根据这些名称创建文件夹,并且是唯一的。所以它只试着创造卡尔一次,而不是57次。之后,它将所有的卡尔、约翰尼和苏西等移动到新文件夹中

如果你是新来的,如果这看起来有点吓人,不要害怕。特别是正则表达式。如果你对正则表达式感到困惑的话,几乎可以肯定有一种不用它们的方法可以做到这一点,但正则表达式是一种工具,一旦你学会了它,你就会意识到它在解决问题方面有多么伟大

[regex]$pattern_name = '^\w.+?(?=[\d\.])'

# create folders for all the unique users
get-Childitem -File -path 'c:\scripts' | foreach-Object {$pattern_name.match($_).value } | sort -unique | foreach-Object { mkdir $_ }

# move files into those folders
get-Childitem -File -path 'c:\scripts' | foreach-Object {
    $user = $pattern_name.match($_).value 
    Move-Item -destination ".\$user" -Path $_.FullName
    }

一种方法。它的作用是:

按用户名对目录中的文件进行分组

如果组有多个文件,它将为用户创建一个目录,然后将用户的文件移动到该目录中

请注意,我将-WhatIf选项添加到所有将 修改数据-您必须删除它们才能实际修改数据 数据


一种方法。它的作用是:

按用户名对目录中的文件进行分组

如果组有多个文件,它将为用户创建一个目录,然后将用户的文件移动到该目录中

请注意,我将-WhatIf选项添加到所有将 修改数据-您必须删除它们才能实际修改数据 数据


以下是一种更简单/更紧凑的方法:

Get-ChildItem | ?{$_.Name -match '(\D+)\d*\.txt'} | %{
  md $matches[1] -ea SilentlyContinue 
  Move-Item $_ $matches[1]
}
纯粹主义者可能会说,在尝试创建目录之前测试路径是更好的做法,但我通常更喜欢更紧凑的代码;如果没有其他决定取决于目录是否已经存在,那么每次尝试创建它并忽略错误会更快

针对OP的评论,有几个解释性说明:

?{}是Where对象的简写,它根据一个条件进行过滤,即只有满足指定条件的对象才能沿着管道传递。因此,在本例中,它获取当前目录的列表,并仅选择Name属性与regex匹配的对象。 使用-match运算符后,匹配项存储在自动数组变量$matches中$matches[0]包含字符串的整个匹配部分,以1开头的索引包含从左括号的顺序位置开始编号的匹配组,即,$matches[1]是从遇到的第一个左括号开始的匹配组,$matches[2]是从第二个左括号开始的匹配组,等等

在这种情况下,只有一个匹配组,$matches[1]包含由\D+匹配的字符串部分,即第一个数字或点之前的连续非数字字符序列


以下是一种更简单/更紧凑的方法:

Get-ChildItem | ?{$_.Name -match '(\D+)\d*\.txt'} | %{
  md $matches[1] -ea SilentlyContinue 
  Move-Item $_ $matches[1]
}
纯粹主义者可能会说,在尝试创建目录之前测试路径是更好的做法,但我通常更喜欢更紧凑的代码;如果没有其他决定取决于目录是否已经存在,那么每次尝试创建它并忽略错误会更快

针对OP的评论,有几个解释性说明:

?{}是Where对象的简写,它根据一个条件进行过滤,也就是说,只有满足指定条件的对象才能向下传递pi 佩林。因此,在本例中,它获取当前目录的列表,并仅选择Name属性与regex匹配的对象。 使用-match运算符后,匹配项存储在自动数组变量$matches中$matches[0]包含字符串的整个匹配部分,以1开头的索引包含从左括号的顺序位置开始编号的匹配组,即,$matches[1]是从遇到的第一个左括号开始的匹配组,$matches[2]是从第二个左括号开始的匹配组,等等

在这种情况下,只有一个匹配组,$matches[1]包含由\D+匹配的字符串部分,即第一个数字或点之前的连续非数字字符序列


+1-请注意,这将为用户创建一个目录,即使他们只有一个文件,这不是OP要求的。同意。虽然这可能是他们想要的:在正则表达式中有一些问题…不是主要的问题,但我想知道你为什么这样写。1.为什么会这样。在正则表达式中的\w之后?虽然名称不可能只有一个字符长,但OP没有指定至少两个字符。另外,为什么只要求类中的第一个字符,然后再匹配任何字符直到第一个数字或句点?这只是一个基于OPs初始语句的快速而肮脏的模式,文件基于人的姓名,末尾带有数字。这种模式当然应该改变,以适应他们的确切需要。至于匹配第一个字符之后的任何字符,这只是我的一个错误。不过,根据所讨论的文件名,如果其中任何一个人名中都有符号,那么这样做可能会更好。底线是正则表达式应该修改以适合他们的具体情况。非常感谢,这正是我所需要的!调整正则表达式,得到我需要的结果。我有一个问题,听起来可能有点傻。我知道$pattern\u name.match$返回一个布尔值,将我的文件名与正则表达式进行比较。。。但是添加.value有什么作用呢?除此之外,我对一切都了如指掌。谢谢大家!+1-请注意,这将为用户创建一个目录,即使他们只有一个文件,这不是OP要求的。同意。虽然这可能是他们想要的:在正则表达式中有一些问题…不是主要的问题,但我想知道你为什么这样写。1.为什么会这样。在正则表达式中的\w之后?虽然名称不可能只有一个字符长,但OP没有指定至少两个字符。另外,为什么只要求类中的第一个字符,然后再匹配任何字符直到第一个数字或句点?这只是一个基于OPs初始语句的快速而肮脏的模式,文件基于人的姓名,末尾带有数字。这种模式当然应该改变,以适应他们的确切需要。至于匹配第一个字符之后的任何字符,这只是我的一个错误。不过,根据所讨论的文件名,如果其中任何一个人名中都有符号,那么这样做可能会更好。底线是正则表达式应该修改以适合他们的具体情况。非常感谢,这正是我所需要的!调整正则表达式,得到我需要的结果。我有一个问题,听起来可能有点傻。我知道$pattern\u name.match$返回一个布尔值,将我的文件名与正则表达式进行比较。。。但是添加.value有什么作用呢?除此之外,我对一切都了如指掌。非常感谢。好吧,这真是太棒了,我就是这么想的。非常感谢。我显然不是powershell专业人士,但我大部分都理解这一点。。。我只是不知道?{}和$matches[1]是什么意思。主要是[1],我不明白。再次感谢你!再次感谢你!很有道理!好吧,这真是太棒了,我就是这么想的。非常感谢。我显然不是powershell专业人士,但我大部分都理解这一点。。。我只是不知道?{}和$matches[1]是什么意思。主要是[1],我不明白。再次感谢你!再次感谢你!很有道理!