如何使用Powershell使用最新文件更新两个目录

时间:2015-07-21 17:52:38

标签: powershell powershell-v2.0

我有两个目录:

C:\G\admin\less
C:\G\user\less

在这些指令中,我有多个less和css文件。我知道文件的所有名称,所以我想将这些文件的列表硬编码到脚本中。也许这可能是在一个数组或其他东西,但我对PowerShell的了解甚至不足以知道脚本语言中是否有数组。

C:\G\admin\less

html-light.less
html-light.css
html-dark.less
html-dark.css
do-not-track-me.less

C:\G\user\less

html-light.less
html-light.css
html-dark.less
html-dairk.css
do-not-track-me.less

有没有办法可以使用PowerShell逐个检查这些文件(我想在程序中进行硬编码),并将最后修改过的文件从其目录复制到另一个目录,这样两个目录都将包含这些文件的最新版本相同吗?

请注意,我需要逐个评估预定义的文件列表。将一个目录中的修改日期与另一个目录进行比较,并根据需要进行复制。

2 个答案:

答案 0 :(得分:1)

再次假设这不是最好的解决方案或方法 该解决方案假定如下   - 当一个文件夹上的LastWriteTime大于另一个文件夹时,它将其复制到另一个文件夹。
  - 由于懒惰,我没有进行路径验证,但如果你想要路径验证,请问。
  - 我假设必须跟踪这些文件夹中的所有文件,否则请阅读代码注释。   - 我建议您在运行脚本之前备份文件夹。

#if there is a file you don't want to track on those folder (for example you don't want to track txt files) 
#just  write $userFiles=dir C:\G\user\less\ -Exclude "*.txt"
#if you don't want track txt but only one of them should be track among with other file format
#$userFiles=dir C:\G\user\less\ -Exclude "*.txt" -Include "C:\G\user\less\Txtadditionaltotrack.txt"
$userFiles=dir C:\G\user\less\
$adminfiles=dir C:\G\admin\less\
foreach($userfile in $userFiles)
{
   $exactadminfile= $adminfiles | ? {$_.Name -eq $userfile.Name} |Select -First 1
   #my suggestion is to validate if it got the file.
   #By now because of my lazy i will not call the test-path to validate if it got the file
   #I'm assuming all directory are exact copy of each other so it will find the file.

  if($exactadminfile.LastWriteTime -gt $userfile.LastWriteTime)
  {
    Write-Verbose "Copying  $exactadminfile.FullName to $userfile.FullName "
    Copy-Item -Path $exactadminfile.FullName -Destination $userfile.FullName -Force
  }
  else
  {
    Write-Verbose "Copying  $userfile.FullName to $exactadminfile.FullName "
    Copy-Item -Path $userfile.FullName -Destination $exactadminfile.FullName -Force
  }
}

你可以改进它,因为这个代码的方式总是将文件从一个目录复制到你可以验证的else中的另一个目录中,这样当lastwriteTime相等时它都不会复制。 您可以通过多种方式改进它。我希望你有意识形态

找到对代码所做的修改,以便它可以达到这个要求 请阅读代码中的评论。
请注意,我没有遵循最佳的做法(避免意外错误,正确命名所有变量,......)

#to make it more dynamical you can save on one file
#all the file names including extension in different lines.
#For example on path C:\FilesToWatch\watcher.txt
#$filestowatch=get-content C:\FilesToWatch\watcher.txt

$filestowatch="felicio.txt","marcos.txt"
$userFiles=dir C:\G\user\less\
$adminfiles=dir C:\G\admin\less\

#Optionally instead of use this if approach you can 

#$userFiles=dir C:\G\user\less\ |? {$filestowatch -contains $_.Name}
#$adminfiles=dir C:\G\admin\less\|? {$filestowatch -contains $_.Name}

#loading in the above manner the first if statement on code bellow can be removed because 
#We make sure that $userFiles and $adminfiles only have correct file to monitor

foreach($userfile in $userFiles)
{
   if($filestowatch -contains $userfile.Name)
   {
      $exactadminfile= $adminfiles | ? {$_.Name -eq $userfile.Name} |Select -First 1
       #my suggestion is to validate if it got the file.
       #By now because of my lazy i will not call the test-path to validate if it got the file
       #I'm assuming all directory are exact copy of each other so it will find the file.

      if($exactadminfile.LastWriteTime -gt $userfile.LastWriteTime)
      {
         Write-Verbose "Copying  $exactadminfile.FullName to $userfile.FullName "
         Copy-Item -Path $exactadminfile.FullName -Destination $userfile.FullName -Force
       }
       else
       {
          Write-Verbose "Copying  $userfile.FullName to $exactadminfile.FullName "
          Copy-Item -Path $userfile.FullName -Destination $exactadminfile.FullName -Force
       }
    }
}

答案 1 :(得分:0)

我认为你需要的是符号链接,也就是符号链接。

使用符号链接,您可以定义始终同步的文件和文件夹,其中目标文件在修改原始文件时自动更新。

要创建符号链接,请在控制台/命令提示符中输入以下内容:

mklink /[command] [link path] [file or folder path]

根据以下命令,Mklink可以创建多种类型的链接:

  • / D - 创建一个软符号链接,类似于Windows中的标准文件夹或文件快捷方式。这是默认选项,如果您不输入命令,mklink将使用它。
  • / H - 创建指向文件的硬链接。
  • / J - 创建指向文件夹的硬链接。

语法很简单。选择您的选项,为符号链接定义所需的路径,最后定义原始文件/文件夹的路径。

例如,想象一下我正在开发一个新项目,我想通过Dropbox共享文件夹将它分享给我的客户端。我不想将我的所有工作区都移动到dropbox,我只想将这个特定文件夹分享给他们:

mklink /J C:\Dropbox\clients_shared_folders\project_x C:\my_dev_rootfolder\project_x

请注意,第一个路径是我想要创建的符号文件夹,而第二个路径是现有目录。

在您的情况下,我将假设您正在处理 admin 文件夹,并希望在用户文件夹中生成同步副本:

mklink /J C:\G\user\less C:\G\admin\less

这是一篇很好的文章以获取更多信息: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/