在一个文件中查找另一个文件中的字符串并输出某些列
Find strings in one file in another and output certain columns
我有一个包含 CampaignNames 和 ID 的文件。这两个字段由竖线 |
分隔。 ID 由 space 分隔。我想在包含 ID 的文件(thorpe þ
分隔)中找到所有行,并将这些行按名称输出到单独的文件中。此文件通常为 4-7 GB,有时更大。
campaigns.txt
:
姓名|姓名 ID
名字|123 212 445 39
名字|313 939
第三名|219
数据 ID 文件:
日期+ID+代码
10-22-14+123+Abc
10-24-16+212+功率
09-18-15+219
所以我想要创建 3 个文件。 FirstName.txt
包含 2 行。 SecondName.txt
包含 0 行。 ThirdName.txt
包含 1 行。
我从各种来源拼凑了一些代码并想出了这个。但是,我想知道是否有比多次读取数据文件更好的方法。有什么想法吗?
$campaigns = Import-Csv "campaigns.txt" -Delimiter "|"
$datafile = "5282_10-19-2016"
$encoding = [Text.Encoding]::GetEncoding('iso-8859-1')
echo "Starting.."
Get-Date -Format g
foreach ($campaign in $campaigns) {
$campaignname = $campaign.CampaignName
$campaignids = $campaign.CampaignID.split(" ")
echo "Looking for $campaignname - $campaignids"
$writer = New-Object System.IO.StreamWriter($campaignname + "_filtered.txt")
foreach ($campaignid in $campaignids) {
$datareader = New-Object System.IO.StreamReader($datafile, $encoding)
while ($dataline = $datareader.ReadLine()) {
if ($dataline -match $campaignid) {
$data = $dataline.Split("þ")
$writer.WriteLine('{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}', $data[0], $data[3], $data[5], $data[8], $data[12], $data[14], $data[19], $data[20])
}
}
}
$writer.Close()
}
echo "Done!"
Get-Date -Format g
只处理一次巨大的数据文件。
从 campaign.txt.
构建的哈希表中选择活动名称
假设没有多少活动(例如,少于 1000)写入尽可能多的 StreamWriters。
$campaignByID = @{}
foreach ($c in (Import-Csv 'campaigns.txt' -Delimiter '|')) {
foreach ($id in ($c.CampaignID -split ' ')) {
$campaignByID[$id] = $c.CampaignName
}
}
$campaignWriters = @{}
$datareader = New-Object IO.StreamReader($datafile, $encoding)
while (!$datareader.EndOfStream) {
$data = $datareader.ReadLine().Split('þ')
$campaignName = $campaignByID[$data[1]]
if ($campaignName) {
$writer = $campaignWriters[$campaignName]
if (!$writer) {
$writer = $campaignWriters[$campaignName] =
New-Object IO.StreamWriter($campaignName + '_filtered.txt')
}
$writer.WriteLine(($data[0,3,5,8,12,14,19,20] -join '|'))
}
}
$datareader.Close()
foreach ($writer in $campaignWriters.Values) {
$writer.Close()
}
要显示进度,请使用基于 $datareader.BaseStream.Position / $datareader.BaseStream.Length * 100
的 Write-Progress
,但不要对每个数据文件行都这样做,因为它会减慢处理速度,每 1 秒执行一次,例如,使用日期时间变量:在经过一秒后更新它并显示进度。
试试这个 ;)
$campaigns=import-csv C:\temp\campaigns.txt -Delimiter "|"
$datafile=import-csv C:\temp82_10-19-2016.txt -Delimiter "þ" -Encoding Default
$DirResult="C:\temp\root"
$campaigns | %{ foreach ($item in ($_.NameID.Split(" "))) {New-Object PSObject -Property @{ Name=$_.Name ; ValID=$item} } } | %{ $datafile | where id -eq $_.ValID | export-csv -Append -Delimiter "|" -Path ("$dirresult\" + $_.ValID + "_filtered.txt") -NoTypeInformation }
我有一个包含 CampaignNames 和 ID 的文件。这两个字段由竖线 |
分隔。 ID 由 space 分隔。我想在包含 ID 的文件(thorpe þ
分隔)中找到所有行,并将这些行按名称输出到单独的文件中。此文件通常为 4-7 GB,有时更大。
campaigns.txt
:
姓名|姓名 ID 名字|123 212 445 39 名字|313 939 第三名|219
数据 ID 文件:
日期+ID+代码 10-22-14+123+Abc 10-24-16+212+功率 09-18-15+219
所以我想要创建 3 个文件。 FirstName.txt
包含 2 行。 SecondName.txt
包含 0 行。 ThirdName.txt
包含 1 行。
我从各种来源拼凑了一些代码并想出了这个。但是,我想知道是否有比多次读取数据文件更好的方法。有什么想法吗?
$campaigns = Import-Csv "campaigns.txt" -Delimiter "|"
$datafile = "5282_10-19-2016"
$encoding = [Text.Encoding]::GetEncoding('iso-8859-1')
echo "Starting.."
Get-Date -Format g
foreach ($campaign in $campaigns) {
$campaignname = $campaign.CampaignName
$campaignids = $campaign.CampaignID.split(" ")
echo "Looking for $campaignname - $campaignids"
$writer = New-Object System.IO.StreamWriter($campaignname + "_filtered.txt")
foreach ($campaignid in $campaignids) {
$datareader = New-Object System.IO.StreamReader($datafile, $encoding)
while ($dataline = $datareader.ReadLine()) {
if ($dataline -match $campaignid) {
$data = $dataline.Split("þ")
$writer.WriteLine('{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}', $data[0], $data[3], $data[5], $data[8], $data[12], $data[14], $data[19], $data[20])
}
}
}
$writer.Close()
}
echo "Done!"
Get-Date -Format g
只处理一次巨大的数据文件。
从 campaign.txt.
构建的哈希表中选择活动名称
假设没有多少活动(例如,少于 1000)写入尽可能多的 StreamWriters。
$campaignByID = @{}
foreach ($c in (Import-Csv 'campaigns.txt' -Delimiter '|')) {
foreach ($id in ($c.CampaignID -split ' ')) {
$campaignByID[$id] = $c.CampaignName
}
}
$campaignWriters = @{}
$datareader = New-Object IO.StreamReader($datafile, $encoding)
while (!$datareader.EndOfStream) {
$data = $datareader.ReadLine().Split('þ')
$campaignName = $campaignByID[$data[1]]
if ($campaignName) {
$writer = $campaignWriters[$campaignName]
if (!$writer) {
$writer = $campaignWriters[$campaignName] =
New-Object IO.StreamWriter($campaignName + '_filtered.txt')
}
$writer.WriteLine(($data[0,3,5,8,12,14,19,20] -join '|'))
}
}
$datareader.Close()
foreach ($writer in $campaignWriters.Values) {
$writer.Close()
}
要显示进度,请使用基于 $datareader.BaseStream.Position / $datareader.BaseStream.Length * 100
的 Write-Progress
,但不要对每个数据文件行都这样做,因为它会减慢处理速度,每 1 秒执行一次,例如,使用日期时间变量:在经过一秒后更新它并显示进度。
试试这个 ;)
$campaigns=import-csv C:\temp\campaigns.txt -Delimiter "|"
$datafile=import-csv C:\temp82_10-19-2016.txt -Delimiter "þ" -Encoding Default
$DirResult="C:\temp\root"
$campaigns | %{ foreach ($item in ($_.NameID.Split(" "))) {New-Object PSObject -Property @{ Name=$_.Name ; ValID=$item} } } | %{ $datafile | where id -eq $_.ValID | export-csv -Append -Delimiter "|" -Path ("$dirresult\" + $_.ValID + "_filtered.txt") -NoTypeInformation }