如何指定目录以运行将编辑文件扩展名的PowerShell脚本?

时间:2018-07-03 17:50:28

标签: powershell directory file-extension

我是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 ".'}看起来正确吗?我不愿意在获得第二意见之前先进行测试,因为我不想更改计算机上的每个文件扩展名或类似的愚蠢文件。无论如何,谢谢大家的帮助。

2 个答案:

答案 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",但我认为这样做没有任何好处。

而且,作为样式选择,$nullwhere-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(还别名为gcilsdir)。 -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}}。