我如何为 运行 将编辑文件扩展名的 PowerShell 脚本指定一个目录?
How would I specify a directory to run a PowerShell script that would edit file extensions?
我是 PowerShell 新手,也是 IT 新手。我的老板要求我编写一个 PowerShell 脚本来识别没有文件扩展名的文件名,然后将它们更改为 .PDF 文件。在网上做了一些研究后,我发现了一个具有类似用途的脚本,并尝试根据我的需要对其进行调整:
$proj_files = Get-ChildItem | Where-Object {$_.Extension -eq "."}
ForEach ($file in $proj_files) {
$filenew = $file.Name + ".pdf"
Rename-Item $file $filenew
}
我的第一个问题是这个脚本中的逻辑是否有意义? "Extension -eq "."
是指定不带扩展名的文件名的正确语法吗?我的另一个想法是使用 Extension -eq "null"
或类似的东西。如果我确实需要使用空值,那会是什么样子?我的另一个问题是如何为该脚本指定一个给定的目录来搜索,或者我什至需要这样做吗?我的想法是在 Get-ChildItem 下指定路径,如下所示: $proj_files = Get-ChildItem -Path C:\Users\mthomas\Documents | Where-Object {$_.Extension -eq ".'}
这样看起来正确吗?在获得第二意见之前,我犹豫是否要对此进行测试,因为我不想更改计算机上的每个文件扩展名或类似的愚蠢内容。总之,谢谢大家的帮助。
脚本中的逻辑 - 整体形状 - 可以理解,但不适合它按您的预期工作。
在我的电脑上测试:
new-item -ItemType File -Name 'test'
get-item test | format-list *
get-item test | foreach { $_.extension; $_.Extension.length; $_.extension.GetType().name }
没有扩展名的文件显示为空字符串(空白内容,长度为 0,类型 String
,因此您的 where-object { $_.Extension -eq "." }
需要查找 ""
而不是 "."
.
但是:
Get-ChildItem | Where-Object { $_.Extension -eq '' }
也显示了一些文件夹,因为它们的名称也没有扩展名,因此您可能希望 Get-ChildItem -File
将其限制为仅文件。
how would I specify a given directory for this script to search through, or would I even need to?
它将 运行 在当前目录中,以提示符 PS C:\wherever>
中显示的那个为准,因此如果您需要它到 运行 其他地方,是的,您需要更改为该文件夹或在 get-childitem -LiteralPath 'c:\path\to\wherever'
中指定。您还没有提到子文件夹,如果您需要包含子文件夹,get-childitem -Recurse
也可以切换。
说到子文件夹,您的 $filenew = $file.Name + ".pdf"
仅在当前目录中有意义,我认为如果您使用包含路径的完整文件名会更好,因此它们肯定会在找到它们的同一位置重命名$filenew = $file.FullName + ".pdf"
Is "Extension -eq "."
the correct syntax to specify a filename with no extension?
请注意,您在问题中所写的语法是正确的,但字符串内容不正确。您在此处用引号在 Extension 左侧写的内容语法不正确。
My other thought was to use Extension -eq "null" or something similar. If I do need to use a null value, what would that look like?
请注意,"null"
不是空值,它是一个包含四个字母单词 'null'.
的字符串
你不需要在这里使用空值,通常如果你这样做看起来像$null
,但在这种情况下你可以使用where-object { [string]::IsNullOrEmpty($_.Extension) }
但是它没有任何好处,我想想。
而且,作为一种文体选择,""
和 ''
都是字符串,但是 ""
可以包含变量和子表达式,所以如果你有纯文本,它是一个整洁的习惯使用 ''
因为它让 reader 清楚地知道您不打算在此字符串中发生任何特殊情况。
那么你的代码,加上参数名称,看起来更像:
$proj_files = Get-ChildItem -LiteralPath 'C:\Users\mthomas\Documents' |
Where-Object {$_.Extension -eq '.'}
foreach ($file in $proj_files)
{
$filenew = $file.FullName + '.pdf'
Rename-Item -LiteralPath $file.FullName -NewName $filenew
}
如果您想看看它会做什么,请在 Rename-Item
的末尾使用 -WhatIf
:
Rename-Item -LiteralPath $file.FullName -NewName $filenew -WhatIf
那么它不会做任何改变,只是告诉你它会做什么。
I am hesitant to test this out before getting a second opinion because I don't want to change every file extension on my computer or something stupid like that
懂事。但是互联网人会告诉你在 运行 之前测试他们的代码,因为最终保护你的文件是你的责任,而不是相信来自互联网的随机代码,所以有测试文件夹,有一台备用机器,有一个好的备份,零散地使用 PowerShell 直到你对它们所做的感到满意,它们都是很好的习惯。
您可以执行类似以下操作来在目录中查找没有扩展名的文件,并将它们重命名为具有 PDF
扩展名:
$directory = "C:\Path\To\Directory"
Get-ChildItem -File $directory | Where-Object { -Not $_.Extension } | Foreach-Object {
$_ | Rename-Item -NewName "$($_.Name).pdf"
}
我们来分解一下
$directory = "C:\Path\To\Directory"
这是我们设置要在其中查找不带扩展名的文件的目录的地方。它不必设置为静态变量,但由于您只是接触 Powershell,所以这很简单。
Get-ChildItem -File $directory
Get-ChildItem
是用于列出目录内容的 cmdlet(也别名为 gci
、ls
和 dir
)。 -File
告诉它只列出文件,$directory
引用我们要从中搜索的目录,我们在上面设置了该目录。请注意,Get-ChildItem
的行为可能因提供者而异(例如,您也可以在注册表项上使用 Get-ChildItem
),但如果您使用的是文件系统路径,则无需担心额外的本案例的提供商。
|
将之前的输出传递到管道中。这是 Powershell 中的常用运算符,但基本上您可以使用它将命令串在一起。您可以在 https://docs.microsoft.com/en-us/powershell/scripting/getting-started/fundamental/understanding-the-windows-powershell-pipeline?view=powershell-6
阅读更多关于管道的信息
Where-Object { -Not $_.Extension }
Where-Object
评估一个或多个项目的条件,并过滤掉不符合条件的项目。由于 Get-ChildItem
可以 return 一个或多个文件,我们在 ScriptBlock
中使用 -Not
运算符(用 {}
表示并确保没有扩展名文件。$_
或 $PSItem
是管道使用的特殊变量,在这种情况下 $_
等于 return 由 Get-ChildItem
编辑的每个项目。 Extension
属性 存在于由 Get-ChildItem
编辑的 return 文件中,并且将为空,或计算为 $False
。因此对 -Not $_.Extension
的过滤是与只匹配缺少文件扩展名的对象相同。Where-Object
可以在此处阅读更多详细信息:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
Foreach-Object { SCRIPTBLOCK }
类似于Where-Object
,但运行为管道中的每个对象编写代码,而不是评估和过滤掉不符合条件的对象。在这种情况下,我们将每个没有扩展名的文件通过管道传输到 Rename-Item
,我将在下面进一步分解。有关 Foreach-Object
的更多信息,请参阅此处:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-6
$_ | Rename-Item -NewName "$($_.Name).pdf"
将 Foreach-Object
块中的当前文件重命名为新名称并附加 .pdf
。 "$( ... )"
称为 sub-expression
,这是一种字符串插值技术,可让您 运行 字符串中的命令,并使其输出成为字符串的一部分。您可以通过执行 $_ | Rename-Item -NewName ( $_.Name + ".pdf" )
来达到相同的效果,它只是在当前名称的末尾添加一个 .pdf
。
总结
管道是 Powershell 中非常强大的工具,是编写高效且不那么臃肿的脚本的关键。一开始它可能看起来很复杂,但是您使用它的次数越多,它看起来就越不令人生畏。我强烈建议阅读我在上面链接的附加文档,因为它应该有助于填补我在上面的解释中可能遗漏的任何空白。
为了简化上面的分解,该命令按以下顺序执行此操作:获取指定目录中的所有文件,仅选择没有扩展名的文件,然后将找到的每个没有扩展名的文件重命名为具有.pdf
最后。
我是 PowerShell 新手,也是 IT 新手。我的老板要求我编写一个 PowerShell 脚本来识别没有文件扩展名的文件名,然后将它们更改为 .PDF 文件。在网上做了一些研究后,我发现了一个具有类似用途的脚本,并尝试根据我的需要对其进行调整:
$proj_files = Get-ChildItem | Where-Object {$_.Extension -eq "."}
ForEach ($file in $proj_files) {
$filenew = $file.Name + ".pdf"
Rename-Item $file $filenew
}
我的第一个问题是这个脚本中的逻辑是否有意义? "Extension -eq "."
是指定不带扩展名的文件名的正确语法吗?我的另一个想法是使用 Extension -eq "null"
或类似的东西。如果我确实需要使用空值,那会是什么样子?我的另一个问题是如何为该脚本指定一个给定的目录来搜索,或者我什至需要这样做吗?我的想法是在 Get-ChildItem 下指定路径,如下所示: $proj_files = Get-ChildItem -Path C:\Users\mthomas\Documents | Where-Object {$_.Extension -eq ".'}
这样看起来正确吗?在获得第二意见之前,我犹豫是否要对此进行测试,因为我不想更改计算机上的每个文件扩展名或类似的愚蠢内容。总之,谢谢大家的帮助。
脚本中的逻辑 - 整体形状 - 可以理解,但不适合它按您的预期工作。
在我的电脑上测试:
new-item -ItemType File -Name 'test'
get-item test | format-list *
get-item test | foreach { $_.extension; $_.Extension.length; $_.extension.GetType().name }
没有扩展名的文件显示为空字符串(空白内容,长度为 0,类型 String
,因此您的 where-object { $_.Extension -eq "." }
需要查找 ""
而不是 "."
.
但是:
Get-ChildItem | Where-Object { $_.Extension -eq '' }
也显示了一些文件夹,因为它们的名称也没有扩展名,因此您可能希望 Get-ChildItem -File
将其限制为仅文件。
how would I specify a given directory for this script to search through, or would I even need to?
它将 运行 在当前目录中,以提示符 PS C:\wherever>
中显示的那个为准,因此如果您需要它到 运行 其他地方,是的,您需要更改为该文件夹或在 get-childitem -LiteralPath 'c:\path\to\wherever'
中指定。您还没有提到子文件夹,如果您需要包含子文件夹,get-childitem -Recurse
也可以切换。
说到子文件夹,您的 $filenew = $file.Name + ".pdf"
仅在当前目录中有意义,我认为如果您使用包含路径的完整文件名会更好,因此它们肯定会在找到它们的同一位置重命名$filenew = $file.FullName + ".pdf"
Is
"Extension -eq "."
the correct syntax to specify a filename with no extension?
请注意,您在问题中所写的语法是正确的,但字符串内容不正确。您在此处用引号在 Extension 左侧写的内容语法不正确。
My other thought was to use Extension -eq "null" or something similar. If I do need to use a null value, what would that look like?
请注意,"null"
不是空值,它是一个包含四个字母单词 'null'.
你不需要在这里使用空值,通常如果你这样做看起来像$null
,但在这种情况下你可以使用where-object { [string]::IsNullOrEmpty($_.Extension) }
但是它没有任何好处,我想想。
而且,作为一种文体选择,""
和 ''
都是字符串,但是 ""
可以包含变量和子表达式,所以如果你有纯文本,它是一个整洁的习惯使用 ''
因为它让 reader 清楚地知道您不打算在此字符串中发生任何特殊情况。
那么你的代码,加上参数名称,看起来更像:
$proj_files = Get-ChildItem -LiteralPath 'C:\Users\mthomas\Documents' |
Where-Object {$_.Extension -eq '.'}
foreach ($file in $proj_files)
{
$filenew = $file.FullName + '.pdf'
Rename-Item -LiteralPath $file.FullName -NewName $filenew
}
如果您想看看它会做什么,请在 Rename-Item
的末尾使用 -WhatIf
:
Rename-Item -LiteralPath $file.FullName -NewName $filenew -WhatIf
那么它不会做任何改变,只是告诉你它会做什么。
I am hesitant to test this out before getting a second opinion because I don't want to change every file extension on my computer or something stupid like that
懂事。但是互联网人会告诉你在 运行 之前测试他们的代码,因为最终保护你的文件是你的责任,而不是相信来自互联网的随机代码,所以有测试文件夹,有一台备用机器,有一个好的备份,零散地使用 PowerShell 直到你对它们所做的感到满意,它们都是很好的习惯。
您可以执行类似以下操作来在目录中查找没有扩展名的文件,并将它们重命名为具有 PDF
扩展名:
$directory = "C:\Path\To\Directory"
Get-ChildItem -File $directory | Where-Object { -Not $_.Extension } | Foreach-Object {
$_ | Rename-Item -NewName "$($_.Name).pdf"
}
我们来分解一下
$directory = "C:\Path\To\Directory"
这是我们设置要在其中查找不带扩展名的文件的目录的地方。它不必设置为静态变量,但由于您只是接触 Powershell,所以这很简单。
Get-ChildItem -File $directory
Get-ChildItem
是用于列出目录内容的 cmdlet(也别名为 gci
、ls
和 dir
)。 -File
告诉它只列出文件,$directory
引用我们要从中搜索的目录,我们在上面设置了该目录。请注意,Get-ChildItem
的行为可能因提供者而异(例如,您也可以在注册表项上使用 Get-ChildItem
),但如果您使用的是文件系统路径,则无需担心额外的本案例的提供商。
|
将之前的输出传递到管道中。这是 Powershell 中的常用运算符,但基本上您可以使用它将命令串在一起。您可以在 https://docs.microsoft.com/en-us/powershell/scripting/getting-started/fundamental/understanding-the-windows-powershell-pipeline?view=powershell-6
阅读更多关于管道的信息Where-Object { -Not $_.Extension }
Where-Object
评估一个或多个项目的条件,并过滤掉不符合条件的项目。由于 Get-ChildItem
可以 return 一个或多个文件,我们在 ScriptBlock
中使用 -Not
运算符(用 {}
表示并确保没有扩展名文件。$_
或 $PSItem
是管道使用的特殊变量,在这种情况下 $_
等于 return 由 Get-ChildItem
编辑的每个项目。 Extension
属性 存在于由 Get-ChildItem
编辑的 return 文件中,并且将为空,或计算为 $False
。因此对 -Not $_.Extension
的过滤是与只匹配缺少文件扩展名的对象相同。Where-Object
可以在此处阅读更多详细信息:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
Foreach-Object { SCRIPTBLOCK }
类似于Where-Object
,但运行为管道中的每个对象编写代码,而不是评估和过滤掉不符合条件的对象。在这种情况下,我们将每个没有扩展名的文件通过管道传输到 Rename-Item
,我将在下面进一步分解。有关 Foreach-Object
的更多信息,请参阅此处:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-6
$_ | Rename-Item -NewName "$($_.Name).pdf"
将 Foreach-Object
块中的当前文件重命名为新名称并附加 .pdf
。 "$( ... )"
称为 sub-expression
,这是一种字符串插值技术,可让您 运行 字符串中的命令,并使其输出成为字符串的一部分。您可以通过执行 $_ | Rename-Item -NewName ( $_.Name + ".pdf" )
来达到相同的效果,它只是在当前名称的末尾添加一个 .pdf
。
总结
管道是 Powershell 中非常强大的工具,是编写高效且不那么臃肿的脚本的关键。一开始它可能看起来很复杂,但是您使用它的次数越多,它看起来就越不令人生畏。我强烈建议阅读我在上面链接的附加文档,因为它应该有助于填补我在上面的解释中可能遗漏的任何空白。
为了简化上面的分解,该命令按以下顺序执行此操作:获取指定目录中的所有文件,仅选择没有扩展名的文件,然后将找到的每个没有扩展名的文件重命名为具有.pdf
最后。