重命名时跳过具有给定前缀的文件
Skipping files with a given prefix when renaming
我有以下脚本用于重命名目录中的一堆文件,将目录的名称添加到它们的开头:
$s = "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
Get-ChildItem -Path $s -Exclude $_.Directory.Name* | rename-item -NewName { $_.Directory.Name + '_' + $_.Name }
在 运行 脚本之前文件夹中的文件看起来像这样
像这样之后
如您所见,它或多或少地完成了我想要的,除了 -exclude $_.DirectoryName*
不会阻止已将文件夹名称作为前缀的文件被重命名。我在这里做错了什么?
$_
只有在管道的右侧使用时才有效,这意味着当你有一个项目集合并且 "pipe" 它们通过“$_”代表当前项目。
由于您要排除的目录名称是静态的,您可以对其进行硬编码并将其用作排除过滤器。
$s = "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
$exclude_filter = "3AJJ000302-222*"
Get-ChildItem -Path $s -Exclude $exclude_filter | rename-item -NewName { $_.Directory.Name + '_' + $_.Name }
也尝试将“-whatif”与重命名项一起使用,这样您就知道会发生什么。
管道中的 $_
仅在 脚本块中定义 用于 非初始 管道段,它指的是手头的输入对象,所以在你的 Get-ChildItem
命令中它实际上是 undefined.
即使 $_.Directory.Name
确实有一个值,$_.Directory.Name*
也不会按预期工作,因为它会被传递为 2 参数(你必须使用 "$($_.Directory.Name)*"
或 ($_.Directory.Name + '*')
.
您反而想从 $s
输入路径中提取目录名称,您可以使用 Split-Path -Leaf
执行此操作,然后附加 '*'
.
为了使-Exclude
有效,输入路径必须以\*
结尾,因为-Include
和-Exclude
过滤器——也许令人惊讶- 对 -Path
参数的叶组件进行操作,而不是对子路径进行操作(除非还指定了 -Recurse
)。
总而言之:
Get-Item -Path $s\* -Exclude ((Split-Path -Leaf $s) + '*') |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name }
我已切换到 Get-Item
,因为 \*
现在用于枚举子项,但 Get-ChildItem
也可以。
$_
表示当前处理的项目,需要 ForEach-Object
或脚本块 在 管道中,不存在于 开始你的命令。
- 解决方案将路径设为 FileInfoObject 并使用 -Exclude
$s = Get-Item "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
Get-ChildItem -Path $s -Exclude "$($s.Name)*"|Rename-Item -NewName {$_.Directory.Name+'_'+$_.Name}
- 解决方案使用
Where-Object
过滤已经以目录名称 开头的文件
Get-ChildItem -Path $s | Where-Object {$_.Directory.Name -notlike "$($_.Name)*"} |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name }
- 解决方案使用基于 RegEx 的
-replace
运算符在目录名称前添加目录名称,并使用 negative lookahead assertion 排除已有目录的文件。
Get-ChildItem -Path $s |
Rename-Item -NewName {$x=$_.Directory.Name;$_.Name -replace "^(?!$x)",$x}
我有以下脚本用于重命名目录中的一堆文件,将目录的名称添加到它们的开头:
$s = "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
Get-ChildItem -Path $s -Exclude $_.Directory.Name* | rename-item -NewName { $_.Directory.Name + '_' + $_.Name }
在 运行 脚本之前文件夹中的文件看起来像这样
像这样之后
如您所见,它或多或少地完成了我想要的,除了 -exclude $_.DirectoryName*
不会阻止已将文件夹名称作为前缀的文件被重命名。我在这里做错了什么?
$_
只有在管道的右侧使用时才有效,这意味着当你有一个项目集合并且 "pipe" 它们通过“$_”代表当前项目。
由于您要排除的目录名称是静态的,您可以对其进行硬编码并将其用作排除过滤器。
$s = "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
$exclude_filter = "3AJJ000302-222*"
Get-ChildItem -Path $s -Exclude $exclude_filter | rename-item -NewName { $_.Directory.Name + '_' + $_.Name }
也尝试将“-whatif”与重命名项一起使用,这样您就知道会发生什么。
-
管道中的
$_
仅在 脚本块中定义 用于 非初始 管道段,它指的是手头的输入对象,所以在你的Get-ChildItem
命令中它实际上是 undefined.即使
$_.Directory.Name
确实有一个值,$_.Directory.Name*
也不会按预期工作,因为它会被传递为 2 参数(你必须使用"$($_.Directory.Name)*"
或($_.Directory.Name + '*')
.您反而想从
$s
输入路径中提取目录名称,您可以使用Split-Path -Leaf
执行此操作,然后附加'*'
.
为了使
-Exclude
有效,输入路径必须以\*
结尾,因为-Include
和-Exclude
过滤器——也许令人惊讶- 对-Path
参数的叶组件进行操作,而不是对子路径进行操作(除非还指定了-Recurse
)。
总而言之:
Get-Item -Path $s\* -Exclude ((Split-Path -Leaf $s) + '*') |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name }
我已切换到 Get-Item
,因为 \*
现在用于枚举子项,但 Get-ChildItem
也可以。
$_
表示当前处理的项目,需要 ForEach-Object
或脚本块 在 管道中,不存在于 开始你的命令。
- 解决方案将路径设为 FileInfoObject 并使用 -Exclude
$s = Get-Item "Y:\Teknisk Arkiv\Likeretter 111-Å1\E2_Kretsskjema_Likeretter styringAJJ000302-222"
Get-ChildItem -Path $s -Exclude "$($s.Name)*"|Rename-Item -NewName {$_.Directory.Name+'_'+$_.Name}
- 解决方案使用
Where-Object
过滤已经以目录名称 开头的文件
Get-ChildItem -Path $s | Where-Object {$_.Directory.Name -notlike "$($_.Name)*"} |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name }
- 解决方案使用基于 RegEx 的
-replace
运算符在目录名称前添加目录名称,并使用 negative lookahead assertion 排除已有目录的文件。
Get-ChildItem -Path $s |
Rename-Item -NewName {$x=$_.Directory.Name;$_.Name -replace "^(?!$x)",$x}