复制项目后,Powershell Remove-Item IF文件已存在

Ref*_*d04 9 powershell

我需要在我的脚本中添加一个安全网.我正在尝试根据通过txt文件提供的用户列表来执行复制作业.将文件从该用户主目录复制到新位置.复制文件后,检查文件是否存在于新位置.如果是,则删除项目.

有人能帮我吗?我只是不知道如何实现"if file exists"逻辑.

$username = Get-Content '.\users.txt'
foreach ($un in $username)
{
  $dest = "\\server\homedirs\$un\redirectedfolders"
  $source = "\\server\homedirs\$un"
  New-Item -ItemType Directory -Path $dest\documents, $dest\desktop

  Get-ChildItem $source\documents -Recurse -Exclude '*.msg' | Copy-Item -Destination $dest\documents
  Get-ChildItem $source\desktop -Recurse -Exclude '*.msg' | Copy-Item -Destination $dest\desktop

  Get-ChildItem $source\mydocuments, $source\desktop -Recurse -Exclude '*.msg' | Remove-Item -Recurse
}
Run Code Online (Sandbox Code Playgroud)

maj*_*tor 19

如果删除文件不存在,删除文件的最短方法是不使用,Test-Path但是:

rm my_file.zip -ea ig

这是短版

rm my_file.zip -ErrorAction Ignore

这更可读,更干

if (Test-Path my_file.zip) { rm my_file.zip }

  • 这不仅更具可读性,而且更正确.首先测试存在的模式是错误的,因为当`Test-Path`以肯定答案返回时,该文件夹可能已被删除,此时调用vanilla`Remove-Item`将引发错误. (2认同)
  • 必须检查 ErrorVariable 违背了使其比 Test-Path 更短的目的。我喜欢这样做:`Get-ChildItem * -Include my_file.zip | 删除项目`。它使我不必两次指定文件名 (2认同)

Adi*_*bar 6

要回答你的问题本身,你可以做这样的:

Get-ChildItem $source\mydocuments, $source\desktop -Recurse -Exclude '*.msg' | %{
  if (Test-Path ($_. -replace "^$([regex]::escape($source))","$dest")) {
    Remove-Item $_ -Recurse
  }
}
Run Code Online (Sandbox Code Playgroud)
  • 如果给定路径上的文件存在,则Test-Path返回$ true,否则返回$ false.
  • $_ -replace "^$([regex]::escape($source))","$dest"通过使用$ dest替换路径开头的$ source,将您枚举的每个源项的路径转换为相应的目标路径.
  • -replace运算符的第一个参数的基本正则表达式^$source(表示"匹配字符串开头的$ source的值").但是,如果$ source包含任何正则表达式特殊字符,需要使用[regex] :: escape,这实际上可能是Windows路径,因为它们包含反斜杠.例如,您在此处为$ source包含的值,在正则表达式中表示"任何空白字符".将使用正确转义的任何正则表达式特殊字符插入$ source的值,以便您匹配显式值.\s$([regex]::escape($source))

也就是说,如果您的目的是将每个项目复制到一个新位置,并且只有在复制到新位置时才删除原始项目,看起来您正在重新发明轮子.为什么不使用Move-Item而不是Copy-Item


与问题没有直接关系,但您可以使用foreach循环,而不是为每个子目录重复相同的命令:

foreach ($subdir in (echo documents desktop)) {
  # Whatever command you end up using to copy or move the items, 
  # using "$source\$subdir" and "$dest\$subdir" as the paths
}
Run Code Online (Sandbox Code Playgroud)