我是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"
或类似的东西。如果确实需要使用null值,那会是什么样?我的另一个问题是如何为该脚本指定给定目录以进行搜索,或者甚至需要?我的想法是在Get-ChildItem下指定路径,例如:$proj_files = Get-ChildItem -Path C:\Users\mthomas\Documents | Where-Object {$_.Extension -eq ".'}
看起来正确吗?我不愿意在获得第二意见之前先进行测试,因为我不想更改计算机上的每个文件扩展名或类似的愚蠢文件。无论如何,谢谢大家的帮助。
答案 0 :(得分:0)
脚本中的逻辑-总体形状-可以理解,但不适合您按预期工作。
在我的计算机上进行测试:
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 "." }
需要查找""
而不是{{1 }}。
但是:
"."
还显示了一些文件夹,因为它们的名称中也没有扩展名,因此您可能希望Get-ChildItem | Where-Object { $_.Extension -eq '' }
将其限制为仅文件。
如何为该脚本指定给定目录以进行搜索,或者甚至需要搜索?
它将在当前目录中运行,无论显示在提示符Get-ChildItem -File
中是什么,因此,如果您需要它在其他地方运行,是的,您需要更改到该文件夹或在PS C:\wherever>
中指定。您没有提到子文件夹,如果需要包含子文件夹,还可以进行get-childitem -LiteralPath 'c:\path\to\wherever'
开关。
说到子文件夹,您的get-childitem -Recurse
仅在当前目录下才有意义,我认为如果使用包含路径的完整文件名会更好,因此它们肯定会在找到的位置重命名{{ 1}}
$filenew = $file.Name + ".pdf"
是正确的语法,用于指定不带扩展名的文件名吗?
请注意,您在问题中写的内容是正确的语法,但字符串内容不正确。您在此处使用扩展名左侧的引号编写的语法不正确。
我的另一个想法是使用扩展-eq“ null”或类似的东西。如果确实需要使用空值,那会是什么样?
请注意,$filenew = $file.FullName + ".pdf"
不是空值,它是一个包含四个字母单词'null'的字符串。
您不需要在此处使用空值,通常情况下,如果您看起来像"Extension -eq "."
,则可以使用"null"
,但我认为这样做没有任何好处。
而且,作为样式选择,$null
和where-object { [string]::IsNullOrEmpty($_.Extension) }
都是字符串,但是""
可以包含变量和子表达式,因此如果您使用纯文本,则习惯是之所以使用''
,是因为它使读者清楚地知道,您打算在此字符串中没有任何特殊的事情。
然后,带有给定参数名称的代码看起来更像:
""
如果要查看其功能,请在''
的末尾使用$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
}
:
-WhatIf
然后它将不会进行更改,只需告诉您它将做什么。
在获取第二意见之前,我不愿进行测试,因为我不想更改计算机上的每个文件扩展名或类似的愚蠢文件
明智的。但是互联网人士会告诉您在运行代码之前先对其进行测试,因为归根结底,保护您的文件是您的责任,而不是信任来自互联网的随机代码,因此拥有测试文件夹,拥有备用计算机,拥有良好的备份,逐步使用PowerShell,直到您对它们的功能感到满意为止,它们都是很好的习惯。
答案 1 :(得分:0)
您可以执行以下操作在不带扩展名的目录中查找文件,并将其重命名为具有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
可以返回一个或多个文件,因此我们在-Not
中使用ScriptBlock
运算符(用{}
表示,并确保文件上没有扩展名。{ {1}}或$_
是管道使用的特殊变量,在这种情况下,$PSItem
等于$_
返回的每个项目。Get-ChildItem
属性存在于文件中由Extension
返回,并且将为空白或评估为Get-ChildItem
。因此,对$False
进行过滤与说仅匹配缺少文件扩展名的对象相同。{{1} },请点击此处详细了解:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6
-Not $_.Extension
类似于Where-Object
,但是为管道中的每个对象运行代码,而不是评估和过滤不符合条件的对象。在这种情况下,我们通过管道将每个文件(不带扩展名)扩展到Foreach-Object { SCRIPTBLOCK }
,我将在下面进一步细分。有关Where-Object
的更多信息,请参见此处:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-6
Rename-Item
将Foreach-Object
块中的当前文件重命名为新名称,并附加$_ | Rename-Item -NewName "$($_.Name).pdf"
。 Foreach-Object
被称为.pdf
,这是一种字符串插值技术,可让您在字符串中运行命令,并使命令的输出成为字符串的一部分。通过执行"$( ... )"
,只需在当前名称的末尾添加一个sub-expression
,即可达到相同的效果。
管道是Powershell中一个非常强大的工具,是编写高效且less肿的脚本的关键。乍一看似乎很复杂,但是使用得越多,看起来就越困难。我强烈建议您阅读我上面链接的其他文档,因为它应该可以弥补我在上面的解释中可能遗漏的任何空白。
为简化上述操作,该命令按以下顺序进行操作:获取指定目录中的所有文件,仅选择不具有扩展名的文件,然后将找到的每个不具有扩展名的文件重命名为具有{{ 1}}。