PowerShell:导入-csv,重命名所有标头 [英] Powershell: Import-csv, rename all headers
问题描述
在我们公司,有许多用户和许多应用程序具有受限访问权限,并且数据库具有这些访问权限的证据。我没有访问该数据库,但我有什么是自动生成(一天一次)CSV文件与我的所有用户的所有访问权限。我希望他们有机会检查他们的访问情况,因此我为此编写了一个简单的PowerShell脚本。
CSV:
user;database1_dat;database2_dat;database3_dat
john;0;0;1
peter;1;0;1
我可以:
import-csv foo.csv | where {$_.user -eq $user}
但这将向我显示原始的难看标题(带有&q;_dat&q;后缀)。当我无法预测明天有多少个标题时,我是否可以从以";_dat";结尾的每个标题中删除最后四个字符?
我知道像这样的计算属性:
Select-Object @{ expression={$_.database1_dat}; label='database1' }
但据我所知,我必须知道它的所有列名。
我是被判定通过单独的函数覆盖&it并动态从头开始构建整个";计算的属性表达式&还是有一种简单的方式我错过了?
谢谢:-)
推荐答案
假设文件foo.csv
作为一个整体可以放入内存中,则以下解决方案运行良好:
- 如果您需要内存限制的解决方案,但速度总是慢得多,请参阅Santiago Squarzon's helpful answer或底部的替代方法。
$headerRow, $dataRows = (Get-Content -Raw foo.csv) -split '
?
', 2
# You can pipe the result to `where {$_.user -eq $user}`
ConvertFrom-Csv ($headerRow -replace '_dat(?=;|$)'), $dataRows -Delimiter ';'
Get-Content
-Raw
将整个文件读取到内存中,这比逐行读取(默认设置)快得多。-split
' ? ', 2
将生成的多行字符串一分为二:标题行和所有剩余行。- 正则表达式
?
匹配换行符(CRLF( , 2
将返回的令牌数量限制为2
,这意味着一旦找到第一个令牌(标题行),拆分就会停止,而输入字符串的其余部分(包括所有数据行)将按原样作为最后一个令牌返回。- 请注意,
$null
是多赋值中的第一个目标变量,它用于丢弃因字符串开头的分隔符正则表达式匹配而产生的空标记。
- 正则表达式
$headerRow -replace '_dat(?=;|$)'
-replace
'_dat(?=;|$)'
使用正则表达式删除所有_dat
列名后缀(后跟;
或字符串末尾);如果子字符串仅作为名称后缀(而不是在名称中)出现,则可以简化为-replace '_dat'
ConvertFrom-Csv
直接接受字符串数组,因此清理后的标题行和包含所有数据行的字符串可以按原样传递。
替代解决方案:对象属性的算法重命名:
注意:此解决方案较慢,但如果您仅从CSV文件中提取几个对象,则可能是一种选择。
正如您在问题中指出的,Select-Object
和calculated properties在您的情况下不是一个选项,因为您事先既不知道列名也不知道它们的编号。
但是,您可以使用ForEach-Object
命令,其中使用.psobject.Properties
、intrinsic member对输入对象进行反射:
Import-Csv -Delimiter ';' foo.csv | where { $_.user -eq $user } | ForEach-Object {
# Initialize an aux. ordered hashtable to store the renamed
# property name-value pairs.
$renamedProperties = [ordered] @{}
# Process all properties of the input object and
# add them with cleaned-up names to the hashtable.
foreach ($prop in $_.psobject.Properties) {
$renamedProperties[($prop.Name -replace '_dat(?=.|$)')] = $prop.Value
}
# Convert the aux. hashtable to a custom object and output it.
[pscustomobject] $renamedProperties
}
这篇关于PowerShell:导入-csv,重命名所有标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!