[英]Powershell - Create a folder from a file name, then place that file in the folder
[英]File and Folder Manipulation in Powershell
我有一个包含数千个文件名的文件夹。
所有文件名都是相对于用户的userID的。 某些用户在此文件夹中有多个文件,因此它将在名称末尾附加一个数字。 IE susy.txt,susy1.txt,susy2.txt,carl.txt,carl1.txt等...
我想要做的是为具有多个文件的每个用户创建一个特定的文件夹,并将所有关联的文件移动到该文件夹中。 因此,我注意到有多个可疑文件。 因此,我想创建一个名为Susy的文件夹,并将susy.txt,susy1.txt和susy2.txt放入其中……对于所有文件,依此类推。
甚至有可能将其作为批处理文件进行处理,如果可以的话,有人可以指出正确的方向吗? 我在编写批处理脚本方面知识很少,并且希望以此为契机来学习更多。
谢谢
这是一种更简单/更紧凑的方法:
Get-ChildItem | ?{$_.Name -match '(\D+)\d*\.txt'} | %{
md $matches[1] -ea SilentlyContinue
Move-Item $_ $matches[1]
}
纯粹主义者可能会说,在尝试创建目录之前,这是Test-Path的“更好的实践”,但是我通常更喜欢紧凑的代码。 如果没有其他决定取决于该目录是否已经存在,则每次尝试创建该目录并忽略错误会更快。
针对OP的评论,有一些解释性注释:
?{ }
是Where-Object的简写,它根据条件进行过滤,即,仅将满足指定条件的对象向下传递到管道。 因此,在这种情况下,它将获取当前目录的列表,并仅选择其Name属性与正则表达式匹配的对象。 使用-match运算符后,匹配项将存储在自动数组变量$ matches中 。 $ matches [0]包含字符串的整个匹配部分,以1开头的索引包含匹配组,从左括号的序号开始编号,即$ matches [1]是从第一个左括号开始的匹配组遇到$ matches [2]是从左下括号开始的匹配组,以此类推。
在这种情况下,只有一个匹配组,并且$ matches [1]包含由(\\D+)
匹配的字符串部分,即,在第一个数字或点之前的连续非数字字符序列。
这是我的快速和肮脏的解决方案。 它使用正则表达式将用户名从文件名中分离出来,即该表达式将从carl1.txt
carl3.txt
carl22.txt
分离出carl
。 然后,它将根据这些名称唯一地创建文件夹。 因此,它仅尝试创建一次carl
,而不是57次。 之后,它将所有的carl
和johnny
和susy
等移到新文件夹中。
如果您是新手,请不要害怕这似乎有点令人生畏。 特别是正则表达式。 如果它们使您感到困惑,几乎可以肯定有一种不用它们的方法,但是正则表达式是那些工具,一旦您学会了它,您就会知道解决问题的能力。
[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选项-您必须删除它们才能实际修改数据。)
# Make backup for safety
cp -recurse .\userFiles .\userFilesBackup
cd .\userFiles
gci | `
select-object @{n='User';e={$_.BaseName -replace "^([a-z]+)[\d]*$", '$1'}}, Name | `
group-object User | `
? { $_.Count -gt 1 } | `
% { `
$userDirectory = $_.Name
mkdir -WhatIf $userDirectory
foreach ($f in $_.Group)
{ mv -WhatIf $f.Name $userDirectory }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.