如何使用 Powershell 使两个目录更新为最新文件
How can I use Powershell to keep two directories updated with the latest files
我有两个目录:
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 逐个检查这些文件(我想在我的程序中进行硬编码)并将最后修改的文件从其目录复制到另一个目录,以便两个目录都将包含这些文件的相同最新版本?
请注意,我需要一个一个地评估预定义的文件列表。将一个目录中的修改日期与另一个目录中的修改日期进行比较,并根据需要进行复制。
我认为您需要的是符号 links,又名 symlinks。
使用 symlinks,您可以定义始终同步的文件和文件夹,当原始文件被修改时,目标文件会自动更新。
要创建符号 link,请在 console/command 提示符中输入以下内容:
mklink /[command] [link path] [file or folder path]
Mklink 可以创建几种类型的 links,根据这些命令:
- /D – 创建软符号 link,类似于 Windows 中的标准文件夹或文件快捷方式。这是默认选项,如果您不输入命令,mklink 将使用它。
- /H – 创建硬 link 文件。
- /J – 创建硬 link 文件夹。
语法简单。选择您的选项,为 symlink 定义您想要的路径,最后是原始 file/folder.
的路径
例如,假设我正在开发一个新项目,我想通过 Dropbox 共享文件夹将其共享给我的客户。我不想将我所有的工作区都移动到保管箱,我只想与他们共享该特定文件夹:
mklink /J C:\Dropbox\clients_shared_folders\project_x C:\my_dev_rootfolder\project_x
注意,第一个路径是我要创建的符号文件夹,而第二个路径是现有目录。
在你的情况下,我假设你在 admin 文件夹上工作,并希望在 user 上生成同步副本]文件夹:
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/
再次假设这不是最佳解决方案或方法
此解决方案假设遵循
- 当一个文件夹上的 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
}
}
你可以改进它,因为这段代码总是将文件从一个目录复制到另一个你可以验证的目录中,这样当两者的 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
}
}
}
我有两个目录:
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 逐个检查这些文件(我想在我的程序中进行硬编码)并将最后修改的文件从其目录复制到另一个目录,以便两个目录都将包含这些文件的相同最新版本?
请注意,我需要一个一个地评估预定义的文件列表。将一个目录中的修改日期与另一个目录中的修改日期进行比较,并根据需要进行复制。
我认为您需要的是符号 links,又名 symlinks。
使用 symlinks,您可以定义始终同步的文件和文件夹,当原始文件被修改时,目标文件会自动更新。
要创建符号 link,请在 console/command 提示符中输入以下内容:
mklink /[command] [link path] [file or folder path]
Mklink 可以创建几种类型的 links,根据这些命令:
- /D – 创建软符号 link,类似于 Windows 中的标准文件夹或文件快捷方式。这是默认选项,如果您不输入命令,mklink 将使用它。
- /H – 创建硬 link 文件。
- /J – 创建硬 link 文件夹。
语法简单。选择您的选项,为 symlink 定义您想要的路径,最后是原始 file/folder.
的路径例如,假设我正在开发一个新项目,我想通过 Dropbox 共享文件夹将其共享给我的客户。我不想将我所有的工作区都移动到保管箱,我只想与他们共享该特定文件夹:
mklink /J C:\Dropbox\clients_shared_folders\project_x C:\my_dev_rootfolder\project_x
注意,第一个路径是我要创建的符号文件夹,而第二个路径是现有目录。
在你的情况下,我假设你在 admin 文件夹上工作,并希望在 user 上生成同步副本]文件夹:
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/
再次假设这不是最佳解决方案或方法
此解决方案假设遵循
- 当一个文件夹上的 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
}
}
你可以改进它,因为这段代码总是将文件从一个目录复制到另一个你可以验证的目录中,这样当两者的 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
}
}
}