用于组合 CSV 并将根目录添加为附加列的 PowerShell 脚本
PowerShell script to combine CSVs and add root directory as an additional column
我正在尝试编写我的第一个 PowerShell 脚本,并且正在努力了解面向对象和管道方法。所以我有这样的目录结构(Google Takeout Nest 目录):
Path\DeviceID-A\
- Year\
- Month\
- year-month-sensors-a.csv
Path\DeviceID-B\
- Year\
- Month\
- year-month-sensors-b.csv
...
我想将所有 CSV 汇总在一起,我编写了一个简单的脚本来执行此操作:
Get-ChildItem -Recurse -Filter *.csv | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv merged.csv -NoTypeInformation -Append
但是,当所有内容聚合在一起时,我丢失了 DeviceID 的上下文。所以我想添加一个包含那些初始根目录的附加列,类似于:
Import-Csv merged.csv | Select-Object *,@{Name='nest_id';Expression={$nestDeviceID}} | Export-Csv merged-v2.csv -NoTypeInformation
因此,year-month-sensors-a.csv 中的每一行都会有一个名为 nest_id
的附加列,其值为 DeviceID-A
用于该根目录下的任何 CSV。
...但是我无法完全协调这两个脚本如何以编程方式遍历它们,无论我需要使用 ForEach-Object
还是管道。
如有任何建议,我们将不胜感激!
在发布代码之前,我认为值得一提的是,只要所有 CSV 始终具有相同的 headers / 列,此 应该可以工作 。如果不是这种情况,可能会发生这样的事情:
@'
Col1,Col2
Val1,Val2
'@ |
ConvertFrom-Csv |
Export-Csv ./test.csv -NoTypeInformation
@'
Col1,NewCol
Val1,NewVal
'@ |
ConvertFrom-Csv |
Export-Csv ./test.csv -NoTypeInformation -Append
这样做会抛出以下异常:
Cannot append CSV content to the following file: ./test.csv. The appended object does not have a property that corresponds to the following column: Col2. To continue with mismatched properties, add the -Force parameter, and then retry the command.
要回答你的问题,你已经很接近了,但是,我认为这不可能作为一个班轮,如果是的话,我当然不会推荐它(阅读你的代码的其他人会为此感谢你).
我的意思是,在不使用循环 (ForEach-Object
or foreach
) 的情况下,将 Get-ChildItem
转换为 Import-Csv
。这是您丢失 DeviceID
文件夹名称引用的地方。
要澄清的要点:
- 代码首先将
$mergedCsv
存储在内存中,在每次循环迭代时将(-Append
)附加到Csv,当不需要时会导致大量不必要的 磁盘 I/O,因此效率不高。在这种情况下,这对您来说可能并不重要,但对您以后的脚本来说是一件好事。
$file.Directory.Parent.Parent.Name
应该给你 DeviceID
文件夹名称,如果我错了请更正。
- 每个循环迭代将导入每个 CSV 并附加包含
DeviceID
文件夹名称的新 Nest_ID
列。
$mergedCsv = foreach($file in Get-ChildItem -Recurse -Filter *.csv)
{
$nestDeviceID = $file.Directory.Parent.Parent.Name
$csv = Import-Csv $file.FullName
$csv | Select-Object *, @{
Name = 'Nest_ID'
Expression = { $nestDeviceID }
}
}
# Inspect the Merged CSV
$mergedCsv | Out-GridView
# Export it
$mergedCsv | Export-Csv merged.csv -NoTypeInformation
我正在尝试编写我的第一个 PowerShell 脚本,并且正在努力了解面向对象和管道方法。所以我有这样的目录结构(Google Takeout Nest 目录):
Path\DeviceID-A\
- Year\
- Month\
- year-month-sensors-a.csv
Path\DeviceID-B\
- Year\
- Month\
- year-month-sensors-b.csv
...
我想将所有 CSV 汇总在一起,我编写了一个简单的脚本来执行此操作:
Get-ChildItem -Recurse -Filter *.csv | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv merged.csv -NoTypeInformation -Append
但是,当所有内容聚合在一起时,我丢失了 DeviceID 的上下文。所以我想添加一个包含那些初始根目录的附加列,类似于:
Import-Csv merged.csv | Select-Object *,@{Name='nest_id';Expression={$nestDeviceID}} | Export-Csv merged-v2.csv -NoTypeInformation
因此,year-month-sensors-a.csv 中的每一行都会有一个名为 nest_id
的附加列,其值为 DeviceID-A
用于该根目录下的任何 CSV。
...但是我无法完全协调这两个脚本如何以编程方式遍历它们,无论我需要使用 ForEach-Object
还是管道。
如有任何建议,我们将不胜感激!
在发布代码之前,我认为值得一提的是,只要所有 CSV 始终具有相同的 headers / 列,此 应该可以工作 。如果不是这种情况,可能会发生这样的事情:
@'
Col1,Col2
Val1,Val2
'@ |
ConvertFrom-Csv |
Export-Csv ./test.csv -NoTypeInformation
@'
Col1,NewCol
Val1,NewVal
'@ |
ConvertFrom-Csv |
Export-Csv ./test.csv -NoTypeInformation -Append
这样做会抛出以下异常:
Cannot append CSV content to the following file: ./test.csv. The appended object does not have a property that corresponds to the following column: Col2. To continue with mismatched properties, add the -Force parameter, and then retry the command.
要回答你的问题,你已经很接近了,但是,我认为这不可能作为一个班轮,如果是的话,我当然不会推荐它(阅读你的代码的其他人会为此感谢你).
我的意思是,在不使用循环 (ForEach-Object
or foreach
) 的情况下,将 Get-ChildItem
转换为 Import-Csv
。这是您丢失 DeviceID
文件夹名称引用的地方。
要澄清的要点:
- 代码首先将
$mergedCsv
存储在内存中,在每次循环迭代时将(-Append
)附加到Csv,当不需要时会导致大量不必要的 磁盘 I/O,因此效率不高。在这种情况下,这对您来说可能并不重要,但对您以后的脚本来说是一件好事。 $file.Directory.Parent.Parent.Name
应该给你DeviceID
文件夹名称,如果我错了请更正。- 每个循环迭代将导入每个 CSV 并附加包含
DeviceID
文件夹名称的新Nest_ID
列。
$mergedCsv = foreach($file in Get-ChildItem -Recurse -Filter *.csv)
{
$nestDeviceID = $file.Directory.Parent.Parent.Name
$csv = Import-Csv $file.FullName
$csv | Select-Object *, @{
Name = 'Nest_ID'
Expression = { $nestDeviceID }
}
}
# Inspect the Merged CSV
$mergedCsv | Out-GridView
# Export it
$mergedCsv | Export-Csv merged.csv -NoTypeInformation