在Powershell中合并命令

时间:2019-02-14 20:03:31

标签: windows powershell variables

我已经使用Windows cmd shell多年了,但是我决定切换到Powershell。

我在cmd shell中的命令,用于对添加日期和时间的文件进行备份:

copy /-Y "D:\MyFiles\workat.txt" d:\bkp_workat_'. strftime("%Y-%m-%d_%H-%M", getftime('D:\MyFiles\workat.txt')) .'.txt'

workat.txt --> bkp_workat_2019-02-14_17-52.txt

powershell中的相同命令:

$RCTime = (ls D:\MyFiles\workat.txt).LastWriteTime 
$myDate = $RCTime.ToString('yyy-MM-dd_HH-mm') 
Copy-Item D:\MyFiles\workat.txt -destination "D:\MyFiles\workat_$myDate.txt"

这很好用,但我需要将3个命令合并为一个命令。

这就是我所做的:

$RCTime = (ls D:\MyFiles\workat.txt).LastWriteTime | $myDate = $RCTime.ToString('yyy-MM-dd_HH-mm') | Copy-Item D:\MyFiles\workat.txt -destination "D:\MyFiles\workat_$myDate.txt"

这会导致错误:Expressions are only allowed as the first element of a pipeline

我怎么了?

4 个答案:

答案 0 :(得分:4)

使用;进行菊花链式独立语句。使用管道(|)将一个命令的输出连接到另一个命令的输入。

您还可以通过菊花链方式对属性和方法进行点访问:

(ls D:\MyFiles\workat.txt).LastWriteTime.ToString('yyy-MM-dd_HH-mm')

但是,原始命令中最PoSh的翻译可能看起来像这样:

Get-Item 'D:\MyFiles\workat.txt' |
    Copy-Item -Destination { 'D:\MyFiles\workat_{0:yyy-MM-dd_HH-mm}.txt' -f $_.LastWriteTime }

或者这个:

Get-Item 'D:\MyFiles\workat.txt' |
    Copy-Item -Destination { Join-Path $_.DirectoryName ($_.BaseName + $_.LastWriteTime.ToString('_yyy-MM-dd_HH-mm') + $_.Extension }

Get-Item从给定的路径生成一个FileInfo对象,并将其通过管道传递给Copy-Item。由于Copy-Item可以从管道读取输入,因此您无需指定源(如来自管道),而只需指定目标。并且由于您正在从管道中读取内容,因此可以使用当前对象变量$_来访问源对象的属性(注意:您需要一个脚本块,即表达式周围的大括号,该脚本块才能起作用)。

第一个示例使用格式运算符-f将日期插入到路径字符串中,第二个示例使用Join-Path cmdlet和字符串串联以根据文件的各种属性构建目标路径输入对象。

答案 1 :(得分:1)

尝试一下:

$RCTime = (ls C:\MyFiles\workat.txt).LastWriteTime;$myDate = $RCTime.ToString('yyy-MM-dd_HH-mm') | Copy-Item D:\MyFiles\workat.txt -destination "C:\MyFiles\workat_$myDate.txt"

您正在尝试将另一个变量传递给另一个变量。因此,为什么会出现错误。只是好奇,为什么要将所有结构都构造成一行?这样做是个好习惯:

$RCTime = (ls C:\MyFiles\workat.txt).LastWriteTime
$myDate = $RCTime.ToString('yyy-MM-dd_HH-mm')
Copy-Item D:\MyFiles\workat.txt -destination "C:\MyFiles\workat_$myDate.txt"

答案 2 :(得分:1)

()是一种将一个命令的结果嵌入到另一个命令的调用中的方法。您基本上是使用$ RCTime设置的

Copy-Item D:\MyFiles\workat.txt -destination "D:\MyFiles\workat_$((ls D:\MyFiles\workat.txt).LastWriteTime.ToString('yyy-MM-dd_HH-mm')).txt"

答案 3 :(得分:1)

管道会根据调用的CMDLET期望显式数据。在您的示例中,您要设置等于CMDLET的变量,然后尝试将其通过管道传递给下一个命令。实际上,每行只能设置一个变量,但是如果您将分号的管道切换出来,它应该可以工作,但不是最佳实践。

如果您想做一个真正的班轮,您需要嵌套通话,看起来像这样。

Copy-Item D:\MyFiles\workat.txt -destination "D:\MyFiles\workat_$($(Get-ChildItem D:\MyFiles\workat.txt).LastWriteTime.ToString("yyyy-MM-dd_HH-mm")).txt"