[玩转系统] 使用 PowerShell 自定义 CSV 导入
作者:精品下载站 日期:2024-12-14 08:03:20 浏览:14 分类:玩电脑
使用 PowerShell 自定义 CSV 导入
我一直在寻找机会使用 PowerShell 来为我的工作增加价值。希望是你的。这是值得花时间和精力学习 PowerShell 的原因之一。除了开箱即用的命令之外,它还可以通过多种方式使用。一旦您了解了 PowerShell 语言并接受了管道中对象的范例,PowerShell 就会提供无限的可能性。就我而言,我想使用本机 Import-Csv 命令执行更多操作。我想保留原来的功能,但我希望它能做更多的事情。我是这样做的。即使您不需要最终结果,我也希望您能够关注 PowerShell 脚本编写技术和概念。这些是您可以应用到您自己的工作中的项目。
复制命令
我首先使用 PSScriptTools 模块中的 Copy-Command 函数。我知道我想添加一些参数和功能。我最初想创建一个代理函数并用我的自定义版本替换 Import-CSV。但最终决定创建一个“包装”函数。这种类型的函数共享传递给它的目标命令的大部分(如果不是全部)参数。 Copy-Command 功能将参数从原始命令复制到新命令。
调整参数
一旦我有了新的参数,我就开始调整。首先,我去掉了 LiteralPath 参数并将其与 Path 参数组合起来。本质上,我将每条路径都视为字面路径。我还添加了自定义参数验证。
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "The path to the CSV file. Every path is treated as a literal path."
)]
[ValidateNotNullOrEmpty()]
#Validate file exists
[ValidateScript({
If ((Test-Path $_) -AND ((Get-Item $_).PSProvider.Name -eq 'FileSystem')) {
$True
}
else {
Write-Warning "Failed to verify $($_.ToUpper()) or it is not a file system object."
Throw "Failed to validate the path parameter."
$False
}
})]
[Alias("PSPath")]
[string[]]$Path,
验证脚本验证路径以及它是否是文件系统对象。
我还知道在导入 CSV 数据时我想添加两个可选功能。首先,我想捕获源文件。我希望它成为自定义输出中的另一个属性。
[Parameter(HelpMessage = "Add a custom property to reflect the import source file.")][switch]$IncludeSource,
我还希望能够定义类型名。从 CSV 文件导入数据时,PowerShell 会将通用自定义对象写入管道。但如果我给它一个类型名称,并使用自定义格式文件(你知道我这样做),我可以改善导入体验。我们稍后会谈到这一点。
System.Collections.Generic.List[]
这两个操作都要求我在使用本机 Import-Csv 命令导入数据后修改数据。请记住,我正在编写一个包装函数,它提供相同的功能以及我的添加内容。因为我需要在导入之后和将对象写入管道之前修改对象,所以我需要一个临时位置来保存它们。从技术上讲,数组是可行的。我可以初始化一个空数组,然后将导入的项目添加到该数组中。但是,从技术上讲,当您向数组添加项目时,PowerShell 会销毁并重新创建该数组。对于小型数据集,这并不是那么重要。但我喜欢尽可能提高效率,所以我一直在使用通用列表。
您可以像这样定义一个新的列表对象:
$in = [System.Collections.Generic.List[object]]::New()
您可以指定列表中的对象类型,例如字符串,或者在我的例子中为通用“对象”。在我的函数中,我利用了Using 语句。在函数之前我有这行代码:
Using Namespace System.Collections.Generic
在我的函数中,这简化了创建列表对象所需的代码。
$in = [List[object]]::New()
您可以使用 Add() 方法将单个对象添加到列表中,也可以使用 AddRange() 一次将多个对象添加到列表中。我没有发现两者之间有太大区别,因此为了简单起见,我将每个导入的项目添加到列表中。
Microsoft.PowerShell.Utility\Import-Csv @PSBoundParameters | ForEach-Object { $in.Add($_) }
请注意,我将 PSBoundParameters 分配给本机命令。我使用的是完全限定的命令名称。这允许我调用我的函数 Import-Csv ,该函数在命令提示符下优先。顺便说一句,我不是。我的函数称为 Import-CsvCustom,但我想包含此函数,以防您决定重命名并演示脚本概念。
自定义对象
有了列表中的所有导入数据,我现在可以修改对象。如果用户指定包含源路径,我将向列表中的对象添加注释属性。
if ($IncludeSource) {
Write-Verbose "[PROCESS] Adding CSVSource property"
$in | Add-Member -MemberType NoteProperty -Name CSVSource -Value $cPath -Force
}
我正在考虑如何将其设为隐藏属性并让我指定属性名称。我的任何 CSV 文件中不太可能有名为 CSVSource 的列。但总的来说,我喜欢有灵活性。
正如我提到的,当您导入 CSV 文件时,您将获得通用自定义对象。
正如您在上图中看到的,我获得了所有对象和属性的列表。但是,如果我有一个已加载到会话中的自定义格式文件怎么办?
Update-FormatData C:\scripts\bedrock.format.ps1xml
现在,我可以导入数据并分配类型名称。
导入-CsvCustom
想亲自尝试一下吗?
#requires -version 5.1
<#
This is a copy of:
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Import-Csv 3.1.0.0 Microsoft.PowerShell.Utility
Created: 17 May 2021
Author : Jeff Hicks
Learn more about PowerShell: https://jdhitsolutions.com/blog/essential-powershell-resources/
#>
<#
I am using a namespace to make defining a List[] object easier later
in the script.
#>
Using Namespace System.Collections.Generic
Function Import-CSVCustom {
#TODO - Add comment-based help
[CmdletBinding(DefaultParameterSetName = 'Delimiter')]
Param(
[Parameter(ParameterSetName = 'Delimiter', Position = 1)]
[ValidateNotNull()]
[char]$Delimiter,
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "The path to the CSV file. Every path is treated as a literal path."
)]
[ValidateNotNullOrEmpty()]
#Validate file exists
[ValidateScript({
If ((Test-Path $_) -AND ((Get-Item $_).PSProvider.Name -eq 'FileSystem')) {
$True
}
else {
Write-Warning "Failed to verify $($_.ToUpper()) or it is not a file system object."
Throw "Failed to validate the path parameter."
$False
}
})]
[Alias("PSPath")]
[string[]]$Path,
[Parameter(ParameterSetName = 'UseCulture', Mandatory)]
[ValidateNotNull()]
[switch]$UseCulture,
[ValidateNotNullOrEmpty()]
[string[]]$Header,
[ValidateSet('Unicode', 'UTF7', 'UTF8', 'ASCII', 'UTF32', 'BigEndianUnicode', 'Default', 'OEM')]
[string]$Encoding,
[Parameter(HelpMessage = "Add a custom property to reflect the import source file.")]
[switch]$IncludeSource,
[Parameter(HelpMessage = "Insert an optional custom type name.")]
[ValidateNotNullOrEmpty()]
[string]$PSTypeName
)
Begin {
Write-Verbose "[BEGIN ] Starting $($MyInvocation.Mycommand)"
Write-Verbose "[BEGIN ] Using parameter set $($PSCmdlet.ParameterSetName)"
Write-Verbose ($PSBoundParameters | Out-String)
#remove parameters that don't belong to the native Import-Csv command
if ($PSBoundParameters.ContainsKey("IncludeSource")) {
[void]$PSBoundParameters.Remove("IncludeSource")
}
if ($PSBoundParameters.ContainsKey("PSTypeName")) {
[void]$PSBoundParameters.Remove("PSTypeName")
}
} #begin
Process {
<#
Initialize a generic list to hold each imported object so it can be
processed for CSVSource and/or typename
#>
$in = [List[object]]::New()
#convert the path value to a complete filesystem path
$cPath = Convert-Path -Path $Path
#update the value of the PSBoundparameter
$PSBoundParameters["Path"] = $cPath
Write-Verbose "[PROCESS] Importing from $cPath"
<#
Add each imported item to the collection.
It is theoretically possible to have a CSV file of 1 object, so
instead of testing to determine whether to use Add() or AddRange(),
I'll simply Add each item.
I'm using the fully qualified cmdlet name in case I want this function
to become my Import-Csv command.
#>
Microsoft.PowerShell.Utility\Import-Csv @PSBoundParameters | ForEach-Object { $in.Add($_) }
Write-Verbose "[PROCESS] Post-processing $($in.count) objects"
if ($IncludeSource) {
Write-Verbose "[PROCESS] Adding CSVSource property"
$in | Add-Member -MemberType NoteProperty -Name CSVSource -Value $cPath -Force
}
if ($PSTypeName) {
Write-Verbose "[PROCESS] Adding PSTypename $PSTypeName"
$($in).foreach({ $_.psobject.typenames.insert(0, $PSTypeName)})
}
#write the results to the pipeline
$in
} #process
End {
Write-Verbose "[END ] Ending $($MyInvocation.Mycommand)"
} #end
} #end Import-CsvCustom
将代码保存到一个文件中,您可以在 PowerShell 会话中点源该文件。然后导入 CSV 文件并尝试一下。该函数应该在 Windows PowerShell 和 PowerShell 7.x 中工作。该函数包括详细输出,并希望有大量内部文档来帮助您理解我在做什么。
我希望您觉得这很有用,或者至少提供了信息。也许您也会开始考虑如何使用 PowerShell 来做更多事情。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag