2014-05-14 81 views
-1

有人能告诉我为什么这个脚本不起作用吗?为什么不重命名文件? Powershell

Get-ChildItem "\\fhnsrv01\home\aborgetti\Documentation\Stage" -Filter *.EDIPROD | ` 
Foreach-Object{ 
    $content = Get-Content $_.FullName 

    #filter and save content to a new file 
    $content | Where-Object {$_ -match 'T042456'} | Rename-Item ` 
                 ($_.BaseName+'_834.txt') 

我在这里发现了另一个问题的这种语法并更改了环境变量。

由于某些原因,它不会更改文件的名称。文件名是

'AIDOCCAI.D051414.T042456.MO.EDIPROD' 

非常感谢。

UPDATE

感谢TheMadTechnician我能得到一些工作的东西。好的东西其实。图我应该与世界分享!

#Call Bluezone to do file transfer 
#start-process "\\fhnsrv01\home\aborgetti\Documentation\Projects\Automation\OpenBZ.bat" 
#Variable Declarations 
$a = Get-Date 
$b = $a.ToString('MMddyy') 
$source = "\\fhnsrv01\home\aborgetti\Documentation\Stage\" 
$dest = "\\fhnsrv01\home\aborgetti\Documentation\Stage\orig" 
#Find all the files that have EDIPROD extension and proceed to process them 
#First copy the original file to the orig folder before any manipulation takes place 
Copy-item $source\*.EDIPROD $dest 
# Now we must rename the items that are in the table 
Switch(GCI \\fhnsrv01\home\aborgetti\Documentation\Stage\*.EDIPROD){ 
    {(GC $_|Select -first 1) -match "834*"}{$_ | Rename-Item -NewName {$_.BaseName+'_834.txt'}} 
    {(GC $_|Select -first 1) -match "820*"}{$_ | Rename-Item -NewName {$_.BaseName+'_820.txt'}} 
} 
+0

你想做什么?只需重命名文件? –

+0

我想看看有.EDIPROD的后缀,这些文件的符合条件的那些需要用的834后缀和.TXT – Hituptony

+0

你检查我的回答一个文件名类型重命名的文件。它为你工作。 – Rahul

回答

1

GET-ChildItem的-Filter有问题,我真的很犹豫,一般使用它。如果是对我我会做这样的事情:

Get-ChildItem "\\fhnsrv01\home\aborgetti\Documentation\Stage" | 
    ?{$_.Extension -match ".EDIPROD" -and $_.name -match "T042456"}| 
    %{$_.MoveTo($_.FullName+"_834.txt")} 

好吧,我会把它全部在一行上,但你可以管后断线之后,它并使它更容易一点阅读, 所以你有它。我在散散步,对不起。

编辑:哇,我甚至没有解决你的脚本有什么问题。对不起,在我工作一天结束的时候,有点分心。那么,为什么你的脚本不工作?原因如下:

您为所选路径拉取文件和文件夹列表。这很好,它应该工作,或多或少,我几乎不相信文件系统提供商的-Filter功能,但无论如何,继续!

你把这个列表,并通过一个foreach循环运行它处理每个符合筛选为这样的文件:

  1. 您读取文件的内容,并将其存储在变量$内容
  2. 你运行文件的内容,一行一行,有一个Where过滤器寻找文本“T042456”
  3. 对于与该文本匹配的每一行,你尝试将某些东西重命名为该行的基本名称加上_834.txt(文本是一个字符串,它没有basename属性,并且它不是一个可以重命名的对象,所以这将会失败l)

所以,这就是问题所在。您正在拉取文件的内容,并逐行解析该文本,以尝试匹配文本而不是匹配文件名。如果您删除了第一个管道到Where语句后的所有内容,然后为您的重命名项目添加-newname,然后将()更改为{ },并绕过新名称,您将被设置。你的代码可以工作。所以,你的代码,修改我说,看起来像:

Get-ChildItem "\\fhnsrv01\home\aborgetti\Documentation\Stage" -Filter *.EDIPROD | 
    Where-Object {$_ -match 'T042456'} | Rename-Item -NewName {$_.BaseName+'_834.txt'} 

虽然我有一种感觉,你想要$ 。名称而不是$ .BaseName。使用$ _基本名称将离开你(使用您的示例文件名):

'AIDOCCAI.D051414.T042456.MO_834.txt` 

EDIT2:真的,这是一个完全不同的问题,如何来匹配多个标准,但问题就在这里,我在这里,为什么不把它完成?

因此,您有多个匹配文件名的条件。这并不影响你的循环,说实话,它影响的是Where语句。如果您有多个选项,您可能需要的是RegEx匹配。完全可行!我只在这里解决Where语句(?{ }),这不会改变脚本中的其他任何内容。

我们保留扩展的一部分,但我们将需要修改文件名部分。使用正则表达式,您可以通过将其放在括号内并与管道字符分开各种选项来匹配替代文本。因此,这将是这个样子:

“(T042456 | T195917 | T048585)”

现在,我们可以结合到Where语句的其余部分,它看起来像这样:

?{$_.Extension -match ".EDIPROD" -and $_.name -match "(T042456|T195917|T048585)"} 

或在你的脚本:

Where-Object {$_ -match "(T042456|T195917|T048585)"} 

EDIT3:嗯,需要在限定的第一道防线。这使事情变得复杂一点。好的,所以我在想的是获取我们的目录列表,获取每个文件的第一行以及所需的扩展名,使对象具有两个属性,第一个属性是文件的fileinfo对象,另一个属性将成为该文件的第一行。等等,我想我们可以做得更好。 Switch(GCI * .EDIPROD){(get-content | select -first 1)-match 820} {Rename 820}; {blah blah -match 834} {rename 834}}。是的,这应该工作。好的,实际的脚本,而不是理论上的乱码脚本时间。这样,如果你有其他的东西要找,你可以为它们添加行。

Switch(GCI \\fhnsrv01\home\aborgetti\Documentation\Stage\*.EDIPROD){ 
    {(GC $_|Select -first 1).substring(177) -match "^834"}{$_ | Rename-Item -NewName {"834Dailyin$b"};Continue} 
    {(GC $_|Select -first 1).substring(177) -match "^820"}{$_ | Rename-Item -NewName {$_.BaseName+'_820.txt'};Continue} 
} 

同样,如果你想EDIPROD部分留在改文件名$_.BaseName$_.Name。如果您尝试根据不同的事情进行匹配并根据结果执行不同的操作,那么Switch非常棒。如果你不熟悉它,你可能想要弯曲你的谷歌肌肉,并检查它。

嗯,另外,我们本来可以在第一线的其中过滤器内部,运行针对一个正则表达式匹配,并改名为基于正则表达式匹配的文件。

GCI \\fhnsrv01\home\aborgetti\Documentation\Stage\*.EDIPROD | ?{(GC $_ | Select -First 1) -match "(820|834)"}|Rename-Item -NewName {$_.Name+"_"+$Matches[1]+".txt"} 

然后,您只需更新Where语句以包含任何您尝试匹配的内容。这很性感,尽管不像开关那样多才多艺。但只是简单的搜索和重命名工作正常。

+0

另一个伟大的答案人感谢解决我的脚本有什么问题。唯一可以学习的方法!非常感激! – Hituptony

+0

还有其他条件可以在同一个目录中匹配。例如,我们在“T042456”上匹配文件名,但其中一些文件将具有“T195917”,其他“T048585”。你会在这里推荐什么样的循环?我知道有几个PowerShell提供的,但ForEach对象好像进入内部...我的文件深处... – Hituptony

+0

好吧,附加答案来帮助你匹配多个文件名。您可能需要花点时间阅读[正则表达式](www.regular-expressions.info),简称RegEx。 – TheMadTechnician

1

尝试像这样

Get-ChildItem -Filter "*T042456*" -Recurse | % {Rename-Item $_ "$_ _834.txt"} 
+1

如果你想指定你需要处理属性的对象的BaseName属性,那么它会给他一个名为类似'AIDOCCAI.D051414.T042456.MO.BaseName_834.txt'的文件,然后将它传递给像字符串'“$ ($ _。基本名称)_834.txt“'。另一方面,我很确定PowerShell会默认将对象转换为文件的名称,因此您可以跳过整个.BaseName位,只需执行“$ __ 834.txt”即可。此外,BaseName将删除.EDIPROD,我不认为这是OP的意图。 – TheMadTechnician

+0

@TheMadTechnician,很高兴知道,谢谢。我不确定如此给予不同的解决方案。 – Rahul

+0

@Rahul我认为TheMadTechnician是正确的,我会接受他的回答,但你绝对接近。谢谢回答! – Hituptony

相关问题