【运维】PowerShell编程 目录文件相关方法的封装与案例详解
目录文件相关方法的封装与案例详解
李俊才 的 CSDN 博客:https://blog.csdn.net/qq_28550263?type=blog
邮箱 :291148484@163.com
CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址:https://blog.csdn.net/qq_28550263/article/details/124378032
本文通过以一个 Path 类,归纳了 Powershell 中常用的文件路径方法。
目 录
1. 获取绝对路径
2. 文件名
3. 获取盘符
4. 当前系统临时目录
5. 文件所在目录名
6. 文件或者目录是否实际存在
7. 获取相对路径
8. 获取目录的当前子项目
9. 递归获取目录的所有子孙项目
10. 在指定目录下筛选文件
11. 在指定目录下筛选目录
12. 获取文件或者目录的修改时间
13. 判断指定路径是否实际是一个文件夹
14. 判断指定路径是否实际是一个文件
15. 判断文件时间是否早于某个值
16. 判断目录是否为空
17. 判断某个路径值是否为绝对路径
18. 获取目录的属性描述符
19. 判 断是否包含某个属性描述符
20. 计算文件或目录的大小
21. 连结多个路径
22. 拆分路径
23. 创建目录
24. Path 环境变量相关方法
25. 删除路径对应的项目
1. 获取绝对路径
static [string]abspath([string]$path){ return Resolve-Path -Path $path; }
如图:
2. 文件名
static [string]basename([string]$path){ return [System.IO.Path]::GetFileName($path)}static [string]basename([string]$path,[bool]$extension=$True){ if($extension){ return [System.IO.Path]::GetFileName($path) } else{ return [System.IO.Path]::GetFileNameWithoutExtension($path) }}
如图:
3. 获取盘符
static [string]rootname([string]$path){ return [System.IO.Path]::GetPathRoot($path)}
【例如】:
4. 当前系统临时目录
static [string]get_temp_path(){ return [System.IO.Path]::GetTempPath()}
【例如】:
5. 获取文件所在目录名
static [string]dirname([string]$path){ return [Path]::basename([System.IO.Path]::GetDirectoryName($path))}static [string]dirname([string]$path, [bool]$absolute=$True){ if($absolute){ return [System.IO.Path]::GetDirectoryName($path) } else{ return [Path]::basename([System.IO.Path]::GetDirectoryName($path)) }}
【例如】:
6. 判断文件或者目录是否实际存在
static [bool] exists([string]$path){ return Test-Path -Path $path}
例如:
7. 获取相对路径
static [string]relpath([string]$relativeTo, [string]$path){ return [System.IO.Path]::GetRelativePath($relativeTo, $path)}
【例如】:
8. 获取目录的当前子项目
static [string[]] get_items([string]$path){ $item_obj = Get-ChildItem $path | Sort-Object $ary = [ArrayList]::new() foreach ($item in $item_obj){ $ary.Add($item.ToString()) } return $ary}static [string[]] get_items([string]$path, [string]$sift){ if($sift -eq 'file'){ $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object; $ary = [ArrayList]::new() foreach ($item in $files){ $ary.Add($item.ToString()) } return $ary }elseif ($sift -eq 'folder') { $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object; $ary = [ArrayList]::new() foreach ($item in $folders){ $ary.Add($item.ToString()) } return $ary }else{ $item_obj = Get-ChildItem $path | Sort-Object $ary = [ArrayList]::new() foreach ($item in $item_obj){ $ary.Add($item.ToString()) } return $ary }}
【例如】:
其中:
- 由于该目录中没有直接子项目为文件,因此当指定第二个参数为
file
时,结果为空; - 指定第二个参数为
folder
和不指定第二个参数的效果完全一致。
9. 递归获取目录的所有子孙项目
static [string[]] get_descendants([string]$path){ $ary = [ArrayList]::new(); $item_obj = Get-ChildItem $path | Sort-Object; # current directory foreach ($item in $item_obj){ if([Path]::is_dirname($item)){ $sub_ary = [Path]::get_descendants($item); $ary.AddRange($sub_ary); } else{ $ary.Add($item); } } return $ary}static [string[]] get_descendants([string]$path, [string]$sift){ $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object; $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object; $ary = [ArrayList]::new() # only file if($sift -eq 'file'){ if($null -ne $files){ foreach ($file in $files){ $ary.Add($file) } } foreach ($item in $folders){ $ary.AddRange([Path]::get_descendants($item,'file')) } } # only dir elseif ($sift -eq 'folder') { if($null -ne $folders){ foreach ($item in $folders){ $ary.Add($item); $ary.AddRange([Path]::get_descendants($item,'folder')) } } } # all else{ $item_obj = Get-ChildItem $path | Sort-Object; # current directory foreach ($item in $item_obj){ if([Path]::is_dirname($item)){ $sub_ary = [Path]::get_descendants($item); $ary.AddRange($sub_ary); } else{ $ary.Add($item); } } } return $ary}
【例如】:
方法 get_descendants
与方法 get_items
的区别在于, get_descendants
的查找范围不限于其自身,还包括其所有的子孙目录。
10. 在指定目录下筛选文件
static [string[]]filter_files([string]$path, [string]$sub_string){ $ary = [ArrayList]::new(); foreach ($item in [Path]::get_items($path,'file')) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary}static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){ $ary = [ArrayList]::new(); if($recursion){ $all = [Path]::get_descendants($path,'file') }else{ $all = [Path]::get_items($path,'file') } foreach ($item in $all) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary}
【例如】:
11. 在指定目录下筛选目录
static [string[]]filter_dirs([string]$path, [string]$sub_string){ $ary = [ArrayList]::new(); foreach ($item in [Path]::get_items($path,'folder')) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary}static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){ $ary = [ArrayList]::new(); if($recursion){ $all = [Path]::get_descendants($path,'folder') }else{ $all = [Path]::get_items($path,'folder') } foreach ($item in $all) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary}
【例如】:
12. 获取文件或者目录的修改时间
static [System.DateTime]get_modify_time([string]$path){ return [System.IO.DirectoryInfo]::new($path).LastWriteTime}
【例如】:
13. 判断指定路径是否实际是一个文件夹
static [bool]is_dirname([string]$path){ return [Path]::has_attributes($path,"Directory")}
【例如】:
14. 判断指定路径是否实际是一个文件
static [bool]is_filename([string]$path){ return -not [Path]::has_attributes($path,"Directory")}
【例如】:
15. 判断文件是否比指定日期新
static [bool]is_newer_than($path, $time){ return Test-Path -Path $path -NewerThan $time}
该方法仅适用于文件系统驱动器。
【例如】:
16. 判断目录是否为空
static [bool]is_empty([string]$path){ if([Path]::is_dirname($path)){ if((Get-ChildItem $path).count -eq 0){ return $True } else{ return $False } } else{ write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. " return $False }}
【例如】:
17. 判断某个路径值是否为绝对路径
static [bool]is_abs([string]$path){ return Split-Path -Path $path -IsAbsolute}
【例如】:
18. 获取目录的属性描述符
static [string[]]get_attributes([string]$path){ return [System.IO.File]::GetAttributes($path).ToString().Split(", ")}
【例如】:
【又如】:
19. 判断是否包含某个属性描述符
static [bool]has_attributes([string]$path, [string]$attributes){ return [Path]::get_attributes($path).Contains($attributes)}
【其中】:
$attributes
的值可以是:
值 | 描述 |
---|---|
Archive |
此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。 |
Compressed |
此文件是压缩文件。 |
Device |
留待将来使用。 |
Directory |
此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。 |
Encrypted |
此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。 |
Hidden |
文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。 |
IntegrityStream |
文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。 |
Normal |
该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。 |
NoScrubData |
文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。 |
NotContentIndexed |
将不会通过操作系统的内容索引服务来索引此文件。 |
Offline |
此文件处于脱机状态, 文件数据不能立即供使用。 |
ReadOnly |
文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。 |
ReparsePoint |
文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。 |
SparseFile |
此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。 |
System |
此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。 |
Temporary |
文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。 |
【例如】:
可以知道,该文件是一个具有 Hidden
的文件(隐藏文件)。
20. 计算文件或目录的大小
static [int64]$counter;static [int64]get_size([string]$path){ [Path]::counter = -1; return [Path]::get_size($path,[Path]::counter)}static [int64]get_size([string]$path,[string]$ParentId){ $count_size = 0; $file_infos = Get-ChildItem $path; # If it is a file, directly return the file size. if($file_infos.Attribute -eq 'Archive'){ write-host $path+" is a file." $count_size = $count_size + $file_infos.Length; } # If it is a directory, the total size is calculated recursively. else{ $count = $file_infos.Count; for ($i = 0; $i -lt $file_infos.Count; $i++) { $child = $file_infos[$i]; [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately. $ID = [Path]::counter; # If it is a file, the size is accumulated. if([Path]::is_filename($child)){ $count_size = $count_size + $child.Length; } # If it is a directory, continue to recursively accumulate the size. else{ $count_size = $count_size + [Path]::get_size($child,$ID) } # 进度条显示 $percent = $i / $count; # 以子条目计算百分比 if($ParentId -eq -1){ Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent; }else{ Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent; } } } return $count_size}
【例如】:
21. 连结路径
static [string]join($path, $childpath){ return Join-Path -Path $path -ChildPath $childpath}
【例如】:
22. 拆分路径
static [string[]]split([string]$path){ $dirname = Split-Path -Path $path -Leaf; $basename = Split-Path -Path $path; return $dirname,$basename}
【例如】:
23. 创建目录
static [void]make($path){ New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" }
【例如】:
其中
- 如果目录完全存在,则会提示错误
"An item with the specified name XXX already exists"
,例如两次重复创建:
- 如果所创建的目录的祖先文件夹都不存在,则会逐个创建祖先文件夹。
24. Path 环境变量相关方法
static [string[]]get_enviroment(){ return [Environment]::GetEnvironmentVariable('Path', 'Machine')}static [void]set_enviroment($path){ [Environment]::SetEnvironmentVariable('Path', $path,'Machine')}static [void]set_enviroment($path,$env_var_target){ if($env_var_target -eq 'Machine'){ [Environment]::SetEnvironmentVariable('Path', $path,'Machine') } elseif($env_var_target -eq 'User'){ [Environment]::SetEnvironmentVariable('Path', $path,'User') } else{ write-host -ForegroundColor Red "ValueError: The value of variable `"`$env_var_target`" can only be one of 'Machine' or 'User'." } }
【例如】:
25. 删除路径对应的项目
static [void] delete([string]$path){ Remove-Item $path;}
【例如】:
附录: Path类代码
using namespace System;using namespace System.Collections;using namespace System.Collections.Generic;class Path{ static [string]abspath([string]$path){ return Resolve-Path -Path $path; } static [string]basename([string]$path){ return [System.IO.Path]::GetFileName($path) } static [string]basename([string]$path,[bool]$extension=$True){ if($extension){ return [System.IO.Path]::GetFileName($path) } else{ return [System.IO.Path]::GetFileNameWithoutExtension($path) } } static [string]rootname([string]$path){ return [System.IO.Path]::GetPathRoot($path) } static [string]get_temp_path(){ return [System.IO.Path]::GetTempPath() } static [string]dirname([string]$path){ return [Path]::basename([System.IO.Path]::GetDirectoryName($path)) } static [string]dirname([string]$path, [bool]$absolute=$True){ if($absolute){ return [System.IO.Path]::GetDirectoryName($path) } else{ return [Path]::basename([System.IO.Path]::GetDirectoryName($path)) } } static [bool] exists([string]$path){ return Test-Path -Path $path } static [string]relpath([string]$relativeTo, [string]$path){ return [System.IO.Path]::GetRelativePath($relativeTo, $path) } static [string[]] get_items([string]$path){ $item_obj = Get-ChildItem $path | Sort-Object $ary = [ArrayList]::new() foreach ($item in $item_obj){ $ary.Add($item.ToString()) } return $ary } static [string[]] get_items([string]$path, [string]$sift){ if($sift -eq 'file'){ $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object; $ary = [ArrayList]::new() foreach ($item in $files){ $ary.Add($item.ToString()) } return $ary }elseif ($sift -eq 'folder') { $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object; $ary = [ArrayList]::new() foreach ($item in $folders){ $ary.Add($item.ToString()) } return $ary }else{ $item_obj = Get-ChildItem $path | Sort-Object $ary = [ArrayList]::new() foreach ($item in $item_obj){ $ary.Add($item.ToString()) } return $ary } } static [string[]] get_descendants([string]$path){ $ary = [ArrayList]::new(); $item_obj = Get-ChildItem $path | Sort-Object; # current directory foreach ($item in $item_obj){ if([Path]::is_dirname($item)){ $sub_ary = [Path]::get_descendants($item); $ary.AddRange($sub_ary); } else{ $ary.Add($item); } } return $ary } static [string[]] get_descendants([string]$path, [string]$sift){ $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object; $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object; $ary = [ArrayList]::new() # only file if($sift -eq 'file'){ if($null -ne $files){ foreach ($file in $files){ $ary.Add($file) } } foreach ($item in $folders){ $ary.AddRange([Path]::get_descendants($item,'file')) } } # only dir elseif ($sift -eq 'folder') { if($null -ne $folders){ foreach ($item in $folders){ $ary.Add($item); $ary.AddRange([Path]::get_descendants($item,'folder')) } } } # all else{ $item_obj = Get-ChildItem $path | Sort-Object; # current directory foreach ($item in $item_obj){ if([Path]::is_dirname($item)){ $sub_ary = [Path]::get_descendants($item); $ary.AddRange($sub_ary); } else{ $ary.Add($item); } } } return $ary } static [string[]]filter_files([string]$path, [string]$sub_string){ $ary = [ArrayList]::new(); foreach ($item in [Path]::get_items($path,'file')) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary } static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){ $ary = [ArrayList]::new(); if($recursion){ $all = [Path]::get_descendants($path,'file') }else{ $all = [Path]::get_items($path,'file') } foreach ($item in $all) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary } static [string[]]filter_dirs([string]$path, [string]$sub_string){ $ary = [ArrayList]::new(); foreach ($item in [Path]::get_items($path,'folder')) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary } static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){ $ary = [ArrayList]::new(); if($recursion){ $all = [Path]::get_descendants($path,'folder') }else{ $all = [Path]::get_items($path,'folder') } foreach ($item in $all) { if([Path]::basename($item).Contains($sub_string)){ $ary.Add($item) } } return $ary } static [System.DateTime]get_modify_time([string]$path){ return [System.IO.DirectoryInfo]::new($path).LastWriteTime } static [bool]is_dirname([string]$path){ return [Path]::has_attributes($path,"Directory") } static [bool]is_filename([string]$path){ return -not [Path]::has_attributes($path,"Directory") } static [bool]is_newer_than($path, $time){ return Test-Path -Path $path -NewerThan $time } static [bool]is_empty([string]$path){ if([Path]::is_dirname($path)){ if((Get-ChildItem $path).count -eq 0){ return $True } else{ return $False } } else{ write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. " return $False } } static [bool]is_abs([string]$path){ return Split-Path -Path $path -IsAbsolute } static [string[]]get_attributes([string]$path){ return [System.IO.File]::GetAttributes($path).ToString().Split(", ") } static [bool]has_attributes([string]$path, [string]$attributes){ return [Path]::get_attributes($path).Contains($attributes) } static [int64]$counter; static [int64]get_size([string]$path){ [Path]::counter = -1; return [Path]::get_size($path,[Path]::counter) } static [int64]get_size([string]$path,[string]$ParentId){ $count_size = 0; $file_infos = Get-ChildItem $path; # If it is a file, directly return the file size. if($file_infos.Attribute -eq 'Archive'){ write-host $path+" is a file." $count_size = $count_size + $file_infos.Length; } # If it is a directory, the total size is calculated recursively. else{ $count = $file_infos.Count; for ($i = 0; $i -lt $file_infos.Count; $i++) { $child = $file_infos[$i]; [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately. $ID = [Path]::counter; # If it is a file, the size is accumulated. if([Path]::is_filename($child)){ $count_size = $count_size + $child.Length; } # If it is a directory, continue to recursively accumulate the size. else{ $count_size = $count_size + [Path]::get_size($child,$ID) } # Progress bar display $percent = $i / $count; # Calculate the percentage by subentry. if($ParentId -eq -1){ Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent; }else{ Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent; } } } return $count_size } static [string]join($path, $childpath){ return Join-Path -Path $path -ChildPath $childpath } static [string[]]split([string]$path){ $dirname = Split-Path -Path $path -Leaf; $basename = Split-Path -Path $path; return $dirname,$basename } static [string[]]get_enviroment(){ return [Environment]::GetEnvironmentVariable('Path', 'Machine') } static [void]set_enviroment($path){ [Environment]::SetEnvironmentVariable('Path', $path,'Machine') } static [void]set_enviroment($path,$env_var_target){ if($env_var_target -eq 'Machine'){ [Environment]::SetEnvironmentVariable('Path', $path,'Machine') } elseif($env_var_target -eq 'User'){ [Environment]::SetEnvironmentVariable('Path', $path,'User') } else{ write-host -ForegroundColor Red "ValueError: The value of variable `"`$env_var_target`" can only be one of 'Machine' or 'User'." }} static [void]delete([string]$path){ Remove-Item $path; } static [void]make($path){ New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" }}