Sql 使用powershell从管道分隔的文本文件中提取列并输出

Sql 使用powershell从管道分隔的文本文件中提取列并输出,sql,excel,powershell,Sql,Excel,Powershell,我需要从一个巨大的管道分隔文件(100MB-3GB)中提取2列(第147列和第148列)。我无法在excel中打开,或者如果我这样做,它将永远无法打开。提取列后,我需要将前N行输出到另一个文本文件中,但我需要对它们进行格式化,以便将它们放入SQL中,以便查询表。但是,在两个提取列中可以有许多由逗号分隔的串联字段(逻辑键字段CLM、逻辑键字段CLM2),其格式因文件而异。我需要这是一个重复的过程 例如,以管道分隔的文件如下所示: |||…|LOGICAL_KEY_CONCAT_FIELD_CLM|

我需要从一个巨大的管道分隔文件(100MB-3GB)中提取2列(第147列和第148列)。我无法在excel中打开,或者如果我这样做,它将永远无法打开。提取列后,我需要将前N行输出到另一个文本文件中,但我需要对它们进行格式化,以便将它们放入SQL中,以便查询表。但是,在两个提取列中可以有许多由逗号分隔的串联字段(逻辑键字段CLM、逻辑键字段CLM2),其格式因文件而异。我需要这是一个重复的过程

例如,以管道分隔的文件如下所示:

|||…|LOGICAL_KEY_CONCAT_FIELD_CLM|LOGICAL_KEY_CONCAT_FIELD_CLM2|||||…
|||…|CLM,KEY,1|CLM,FINANCIAL,KEY,1,2018-11-30|||…
|||…|CLM,KEY,2|CLM,FINANCIAL,KEY,2,2018-11-30|||…
|||…|CLM,KEY,3|CLM,FINANCIAL,KEY,3,2018-11-30|||…
.
.
.
输出:

(LOGICAL_KEY_CONCAT_FIELD_CLM = 'CLM,KEY,1' AND 
LOGICAL_KEY_CONCAT_FIELD_CLM2 = 'CLM,FINANCIAL,KEY,1,2018-11-30')
OR (LOGICAL_KEY_CONCAT_FIELD_CLM = 'CLM,KEY,2' AND 
LOGICAL_KEY_CONCAT_FIELD_CLM2 = 'CLM,FINANCIAL,KEY,2,2018-11-30')
OR (LOGICAL_KEY_CONCAT_FIELD_CLM = 'CLM,KEY,3' AND 
LOGICAL_KEY_CONCAT_FIELD_CLM2 = 'CLM,FINANCIAL,KEY,3,2018-11-30')
基本上,我希望使用文件中列的数据运行查询,并希望确保表中包含逻辑键字段和逻辑键字段的组合。我不需要从表中选择*,因为表随传入源的不同而变化

我正在使用以下代码,但它不打印输出文件中的列,只打印标题:

Get-Content "\\LocationOfFile\CLAIM_20190103T17053920.txt" | select-object 
LOGICAL_KEY_CONCAT_FIELD_CLM,LOGICAL_KEY_CONCAT_FIELD_CLM2 -First 10 | Out- 
File "P:\PDS_QA\TestFile\Output.txt"

这可能是最快的选择(?)

由于您的文件非常大,因此它使用一些.NET流来实现最佳性能:

$outstream = New-Object System.IO.StreamWriter "P:\PDS_QA\TestFile\Output.txt"
try {
    $outstream.WriteLine("SELECT * FROM Table WHERE 1=0")
    $firstLine = $true
    foreach ($line in [System.IO.File]::ReadLines("\\LocationOfFile\CLAIM_20190103T17053920.txt")) {
        if ($firstLine) {
            # skip the header of the file
            $firstLine = $false
            continue
        }
        $values = $line.Split("|")
        # (-1 because I assume your column numbers are one-based)
        $clm, $clm2 = $values[146, 147]
        $line = "OR (LOGICAL_KEY_CONCAT_FIELD_CLM = '{0}' AND LOGICAL_KEY_CONCAT_FIELD_CLM2 = '{1}')" -f $clm, $clm2
        $outstream.WriteLine($line)
    }
}
finally {
    $outstream.Dispose()
}

替代解决方案,使用纯内置PowerShell cmdlet。我说不出大文件的性能有多好。可能比我的另一个答案更糟。你应该试试看

此外,这要求输入CSV有一个标题,每个列都有唯一的名称

$infile = "\\LocationOfFile\CLAIM_20190103T17053920.txt"
$outfile = "P:\PDS_QA\TestFile\Output.txt"
"SELECT * FROM Table WHERE 1=0" | Out-File $outfile
Import-Csv $infile -Delimiter "|" | foreach {
    "OR (LOGICAL_KEY_CONCAT_FIELD_CLM = '{0}' AND LOGICAL_KEY_CONCAT_FIELD_CLM2 = '{1}')" -f (
    $_.LOGICAL_KEY_CONCAT_FIELD_CLM,
    $_.LOGICAL_KEY_CONCAT_FIELD_CLM2)
} | Out-File $outfile -Append

不清楚您的要求是什么,使用“选择对象”可以选择属性/列,但使用“获取内容”可以获得纯文本,而没有对象属性。从您的示例数据来看,不清楚是否所有标题都是唯一的。通常使用
Import Csv yourfile.Csv-分隔符“|”
在中读取文件。(或者用
Get Content yourfile.csv | select object-first 11 | convert From csv-Delmiter'|'
)将第一次读入的行数减少到前n+1行)您的意思是这样的
import csv.\claim.txt-分隔符“|”|选择对象逻辑键_CONCAT_字段|CLM,逻辑键连接字段CLM2-前2个导出Csv。\test.txt-NoTypeInformation
?你想用输出做什么?Hanks@Razorfen,这是我需要的一部分。我计划将输出放入SQL,在那里我可以输入SELECT | FROM | where子句,然后将PS脚本的输出粘贴到where子句。您知道如何在输出文件中添加OR(LOGICAL_KEY_CONCAT_FIELD_CLM='OutputFromFirstColumn'和LOGICAL_KEY_CONCAT_FIELD_CLM2='OutputFromSecondColumn')吗?@jujulalu Razorfen是正确的,但对于这样大的文件,性能可能会有点差。你应该试试看。看看我的更新答案和解释纯PS解决方案的新答案。我会将拆分缩短为
$CLM,$CLM2=$line.split(“|”)[146..147]
(我讨厌超长变量名)(+1)@LotPings同意。实际上,我以前用过短名字,但在我发布答案时用长名字代替了短名字。谢谢@marsze,我不得不在for-each循环之前添加一行代码,但它按照我的意愿工作。我添加了粗体代码:导入Csv$infle-分隔符“|”|选择逻辑键_CONCAT _字段_RX,逻辑键连接字段前1000个foreach