从.txt文件中提取数据以使用powershell填充.csv文件

时间:2017-09-05 13:42:11

标签: powershell csv

我们每天向供应商提供一个合并的.csv文件,其中包含销售订单。由于第四季度我们的基础架构发生了已知的变化,我们正在失去管理此整合的应用程序,需要以某种方式手动开发。

我们从.txt文件中接收订单,但实际上它们看起来像.csv。文件看起来像这样

OR,00000330,9217,,20170904,,
,AG147,,,3.25,,1
,AG161,,,2.69,,2
,AG001,,,2,,2
,AG004,,,2,,2
,AG005,,,1.9,,2
,AG008,,,1.9,,2
,AG009,,,1.9,,2
,AG010,,,2.03,,2
,AG011,,,1.9,,2
,AG012,,,1.9,,2
,AG013,,,2.35,,2
,AG014,,,2.35,,2
,AG015,,,2.35,,2
,AG016,,,2.11,,2

我需要从这些文件中提取(并非所有文件都包含相同的数据):

  • 9217 - 唯一商店标识
  • 20170904 - 交货日期
  • AGXXX - 产品代码
  • 最后价值 - 产品数量

正如您从文件中看到的那样,它不会显示标题或列名称。所以我已经遇到了一些问题。

就最终.csv文件需要的内容而言,这是一个例子。我已在标题中手动编辑,同样,此文件没有标题信息。

SiteCode    SiteName    Address2    Address3    County  PostCode    Contactno   ?   Product Quantity    ?   ProuctCode  TransactionDate DeliveryDate
7001    Site    10 Big Street   The Big Street  Co.County   XXX-XXX 123456  1840246 ABC123  4   77168   Chicken Stuffing WB 01/08/2017  03/08/2017

""标题表示我等待确认它们的列。

很明显,csv中有很多未包含在销售订单中的内容。

  • SiteCode - 这是销售订单
  • SiteName - 我知道这一点,我可以在脚本中有代码,当SiteCode = X然后Sitename = y?
  • 地址 - 我知道这一点,我可以在脚本中有代码,当SiteCode = x时,地址行= y?
  • 郡 - 与上述相同
  • PostCode - 与上面相同
  • Contactno - 与上述相同
  • H栏未知 - 需要找出这个值是什么
  • 产品代码 - 需要从销售订单中提取和填充
  • 数量 - 需要从销售订单中提取和填充
  • 列K未知 - 每行的授权值相同。我可以为每一行定义要在此列中插入的值吗?
  • ProductName - 不在销售档案中,但我知道名字。我可以通过PowerShell从数据库中提取它还是在脚本中定义它?当ProductCode = X时 - PRoductName = Y?
  • TransactionDate - 这是订单提出的日期。它在文件名中,我可以从文件名中提取到填充列吗?
  • DeliveryDate - 这是销售订单中的第一行

非常感谢大家的帮助。我有一些工作但正在努力让数据提取工作在这里。

2 个答案:

答案 0 :(得分:2)

基本上看起来你有一堆带有逗号分隔值的文件(但不是实际的CSV,因为第一行中的数据不是标题,也与其他数据不同),并希望将其导出为TSV(制表符分隔值)文件。

由于您的输入数据实际上不是CSV,因此我不会为Import-Csv而烦恼。只需将文件作为文本读取并拆分行即可。

$data = Get-Content 'C:\path\to\input.txt'

$store, $date = (($data | Select-Object -First 1) -split ',')[2, 4]

$data | Select-Object -Skip 1 | ForEach-Object {
    $product, $qty = ($_ -split ',')[1, -1]
    ...
}

通过PowerShell中的哈希表来查找另一个值的一个值:

$sites = @{
    'foo' = 'Site A'
    'bar' = 'Site B'
    ...
}
$sitecode = 'bar'

$sites[$sitecode]    # returns 'Site B'

哈希表的值不需要是简单的字符串,你也可以在那里拥有嵌套的哈希表,数组或其他对象。例如,查找地址数据的哈希表可能如下所示:

$addresses = @{
    'foo' = New-Object -Type PSObject -Property @{
        'Address' = 'Runaway Avenue 23'
        'Country' = 'Greenland'
        'Postcode' = 12345
        ...
    }
    'bar' = New-Object  -Type PSObject -Property @{
        ...
    }
    ...
}

根据输入数据和哈希表构建自定义对象:

New-Object -Type PSObject -Property @{
    'SiteCode' = $sitecode
    'SiteName' = $sites[$sitecode]
    'Address2' = $addresses[$sitecode].Address
    'Postcode' = $addresses[$sitecode].Postcode
    ...
    'Quantity' = $qty
    ...
}

并通过Export-Csv将生成的对象导出到TSV文件:

... | Export-Csv 'C:\path\to\output.csv' -NoType -Delimiter "`t"

答案 1 :(得分:0)

要求整个脚本执行您想要的操作是不道德的。所以这就是让你前进的原因。

当我将该示例数据复制到文件时,比如data.txt并将其读入变量

$Data = get-content C:\Data.txt

这是我注意到的模式 $Data[0]是包含唯一商店标识符和投放日期的第一行 所以$UniqueStoreId = $data[0].Split(",")[2]

$DeliveryDate = ([datetime]::ParseExact($data[0].Split(",")[4],”yyyyMMdd”,$null)).toshortdatestring()

然后,如果总行数$Total = $data.Count

迭代for循环中的每一行,如下所示。你将拥有你需要的一切。

For ($I=1; $I -lt $Total; $I++)
{
    $ProductCode = $Data[$I].Split(",")[1]
    $Quantity = $Data[$I].Split(",")[6]
}

创建自定义CSV文件很简单。创建一个新的PSObject并添加您需要的标题作为其属性。对此进行Export-CSV会将结果传递给完美的csv。

$CSVobject = [PSCustomObject] @{
        Header1 = $null
        Header2 = $null
        Header3 = $null
        #and so on
    }

在for循环中,将您提取的数据添加到CSVObject,如

$CSVObject.Header1 = "xxxx"
$CSVObject.Header2 = "yyyy"

在循环中运行此全部内容,或者您​​希望获得最终的CSV。下面是一个粗略的例子

$FinalCSV = For ($I=1; $I -lt $Total; $I++)
{
    $ProductCode = $Data[$I].Split(",")[1]
    $Quantity = $Data[$I].Split(",")[6]

    $CSVobject.Header1 = $ProductCode
    $CSVObject.Heade2 = "$Quantity"

    $CSVObject
}

最后,执行Export-CSV以获得所需的输出。