【问题标题】:PowerShell: I need to understand why parameters are interpreted as NULLPowerShell:我需要了解为什么参数被解释为 NULL
【发布时间】:2013-01-11 09:12:53
【问题描述】:

我收到一个错误,我无法在空值表达式上调用方法。但是,我不确定为什么参数会导致空值。我需要第二双眼睛来看待这个并给我一些指导。

$docpath = "c:\users\x\desktop\do"
$htmPath = "c:\users\x\desktop\ht"
$txtPath = "c:\users\x\desktop\tx"
$srcPath = "c:\users\x\desktop\ht"
#
$srcfilesTXT = Get-ChildItem $txtPath -filter "*.htm*"
$srcfilesDOC = Get-ChildItem $docPath -filter "*.htm*"
$srcfilesHTM = Get-ChildItem $htmPath -filter "*.htm*"
#
function rename-documents ($docs) {  
    Move-Item -txtPath $_.FullName $_.Name.Replace("\.htm", ".txt") 
    Move-Item -docpath $_.FullName $_.Name.Replace("\.htm", ".doc") 
}
ForEach ($doc in $srcpath) {
    Write-Host "Renaming :" $doc.FullName         
    rename-documents -docs  $doc.FullName   
    $doc = $null   
}

还有错误....

You cannot call a method on a null-valued expression.
At C:\users\x\desktop\foo002.ps1:62 char:51
+     Move-Item -txtPath $_.FullName $_.FullName.Replace <<<< ("\.htm", ".txt")
    + CategoryInfo          : InvalidOperation: (Replace:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\users\x46332\desktop\foo002.ps1:63 char:51
+     Move-Item -docpath $_.FullName $_.FullName.Replace <<<< ("\.htm", ".doc")
    + CategoryInfo          : InvalidOperation: (Replace:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

首先:我的("\.htm", ".txt") 似乎显示为空。我在没有\ - (".htm", ".txt") 的情况下也试过了,并且得到了相同的结果。

第二:从句法上讲,我将我的行解释为move-item &lt;path&gt; &lt;source-file-passed-to-function&gt; &lt;replacement=name-for-file&gt; (parameters-for-replacement)。这是对这段代码在做什么的适当理解吗?

第三:我需要在某个地方有一个-literalpath 参数吗? MS TechNet 和 get-help 关于-literalpath 参数的使用信息很少;我无法找到与我的特定情况相关的东西。

帮助我了解我缺少什么。谢谢!

【问题讨论】:

  • 第一:$srcpath 包含 "c:\users\x\desktop\ht" 作为字符串,而不是文件列表。第二:对于您的 move-item 这 -> -txtpath 是要移动的文件的名称,而不是路径。在你的问题中描述你的目标到底是什么。
  • 第三个:-literalpath 根据您的先例问题move-item 需要stackoverflow.com/a/14259748/520612
  • 目标:我正在尝试将一批文件从 *.foo 重命名为 *.bar。重命名必须是脚本中的函数。该脚本已经设置了需要传递给函数的路径变量。
  • 尝试关注@keithill 的回答,它会以正确的方式出现!

标签: powershell nullreferenceexception file-rename


【解决方案1】:

在一个简单函数的上下文中$_ 没有定义。 $_ 仅在管道中有效。也就是说,$_ 表示正在向下传递管道的当前对象。

用你当前的函数定义试试这个方法:

function Rename-HtmlDocument([System.IO.FileInfo]$docs, $newExt) {  
    $docs | Move-Item -Dest {$_.FullName -replace '\.htm$', $newExt} 
}

您可以将$srcfilesDOC 和$srcFilesTXT 变量直接传递给此函数,例如:

Rename-HtmlDocument $srcFilesDOC .doc
Rename-HtmlDocument $srcFilesTXT .txt

当然,你可以让它更通用,并从 FileInfo 对象获取源扩展,例如:

function Rename-DocumentExtension([System.IO.FileInfo]$docs, $newExt) {  
    $docs | Move-Item -Dest {$_.FullName.Replace($_.Extension, $newExt)} 
}

BTW PowerShell 的 Move-Item 命令没有您使用的参数 -txtPath 和 -docPath。这是您创建的函数吗?

【讨论】:

  • -txtPath 和 -docPath 应该是 $txtPath 和 $docPath (如上定义),这是问题的一部分,我敢肯定。我要搞乱你的解决方案。鉴于我必须使用的脚本,它看起来可能对我有用。
  • 这一切都是从这里开始的:stackoverflow.com/a/14259748/520612 现在我正在查看您的解决方案,RenameItem ~可能~不起作用。
  • .Replace("…","…") 中的点无需转义,在使用-replace "…","…" 时,第一个参数中需要它,因为它随后被视为正则表达式。这也是我更喜欢后者的原因,因为您可以添加尾随 $,因为您的意思是仅替换扩展名(在最后)。
  • 仅更改文件扩展名, • 在替换 regex 末尾添加$, • 使用.BaseName(不包括驱动器、文件夹和扩展名),或 • 使用[IO.Path]::ChangeExtension(…)
  • @mousio $ metachar 的要点。我也喜欢使用[IO.Path]::ChangeExtension()。在 PowerShell 中有很多方法可以给这只猫剥皮。
猜你喜欢
  • 2016-02-14
  • 2011-02-22
  • 1970-01-01
  • 2015-04-22
  • 2017-01-20
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多