Powershell脚本需要根据定义的列表编辑行中分隔符之间的项

Powershell脚本需要根据定义的列表编辑行中分隔符之间的项,powershell,csv,replace,find,Powershell,Csv,Replace,Find,您好,谢谢您的阅读。这是我的第一篇文章,真的需要一些帮助。最难的部分是让人们理解我的问题。我会尽力的 我有一些巨大的csv文件(有些超过800万行,所以Excel不是一个选项),我需要根据参考文件中定义的单词集修改每行第三个“字段”的内容 因此,csv示例可能类似于: AB12|TEST|CAT DOG MOUSE|TEST1|TEST2|TEST3||TEST4 CD34|TEST|HORSE CART TRAIN|TEST1|TEST2|TEST3||TEST4 等等 在我的参考文件中,

您好,谢谢您的阅读。这是我的第一篇文章,真的需要一些帮助。最难的部分是让人们理解我的问题。我会尽力的

我有一些巨大的csv文件(有些超过800万行,所以Excel不是一个选项),我需要根据参考文件中定义的单词集修改每行第三个“字段”的内容

因此,csv示例可能类似于:

AB12|TEST|CAT DOG MOUSE|TEST1|TEST2|TEST3||TEST4

CD34|TEST|HORSE CART TRAIN|TEST1|TEST2|TEST3||TEST4
等等

在我的参考文件中,我有一个列表,例如:

CAT

HORSE CART
这些文件包含在CSV文件中

我需要的是修改文件,以便第三个“字段”(将第二个“|”之后和第三个“|”之前的所有内容与参考列表进行比较,并进行修改以匹配。即在第一行中,CAT之后的所有内容将被删除,在第二行中,马车之后的所有内容将在第三个字段中被删除。因此输出的结果文件如下所示:

AB12|TEST|CAT|TEST1|TEST2|TEST3||TEST4

CD34|TEST|HORSE CART|TEST1|TEST2|TEST3||TEST4
我通常使用F.A.R.T来修改大文件,但这需要比FART提供的更聪明一点

我真的希望这对其他人来说是有意义的,并感谢你可能提供的任何帮助

到目前为止,我一直在尝试这一点,但距离实现我的目标还有很长的路要走:

cls

$content = ""

write-output "** Original String **"
write-output ""

$content = Get-Content "~\Desktop\Test\*.dat" 

$content

$separator1 = " " 
$separator2 = "|" 

$parts = $content.split($separator1)

write-output ""
write-output "** Revised String **"
write-output ""

$part1 = echo $parts[0]
$part3 = $part2.split($separator2)

$part4 = $part3[1]

$revised = $part1, $part4 -join "|"



$revised

write-output ""

总之,这是一个经过修改的“查找并替换文本”函数,它集中于每行中的一个字段,查找匹配的词集,然后删除该字段中除在单独的csv文件中定义的匹配词以外的所有内容。

好,因为PowerShell中的比较数组不支持通配符必须用老式的(昂贵的)方法来做这件事。将每个字段与每个引用进行比较

我没有提供一个读取文件的示例,因为在速度或内存消耗方面(您的选择),可以通过不同的方式读取文件

此外,我还将引用作为一个数组提供,而不是作为一个文件输入,以使示例切中要害(并且易于测试)

当然,输出应该写入一个新文件,而不是写入主机

$file = @"
F1|F2|F3|F4|F5|F6|F7|F8
AB12|TEST|CAT DOG MOUSE|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART TRAIN|TEST1|TEST2|TEST3||TEST4
CD34|TEST|HORSE CART|TEST1|TEST2|TEST3||TEST4
"@

$ref = @("CAT*","HORSE CART*")


$file.split("`n") | foreach {# line in file
    $outline = $nul
    $_.split('|') | foreach {# field in the line
        $field = $_
        $refhit = $false
        $ref | foreach {# item in the ref array
            if ($field -like $_) {# replace field with ref
                $refhit = $true
                $outline += $_.TrimEnd('*') + '|'
            }# end match
            
        }# end ref

        if (!$refhit){#pass on the field as is
            $outline += "$field|" 
        }
        
    }#end field

    # Output filtered line
    write-host $outline.TrimEnd('|')

}#end line


因此,您必须根据每个参考值测试第三列?正确。我目前正在尝试在Notepad++中查找和替换,但尽管我可以跨多个大文件执行此操作,但我不能同时执行多个更改。参考文件可能有多达1000个条目,因此您需要根据1000个条目检查第三列中的每一行d项?可能。如果有一种方法可以在NPP中进行多行查找和替换,那么就可以了。但是,由于更改列表太大,我认为这不是一个选项。参考csv文件(其中包含数千个关键字)是否有标题,或者只是一个单独一行的关键字列表?嗨,丹尼斯,非常感谢你看这个。我能澄清几件事吗?嗨,丹尼斯,非常感谢你看这个。我能澄清几件事吗?1.当你说powershell不处理通配符时,那么在引用数组?(CAT*)2.有没有办法只比较主文件的第三段,因为这是唯一需要更改的字段。3.内存不是问题,因此如果您能添加几行,以显示将整个文件(以及引用文件)读入内存的最佳方式,我将不胜感激然后是输出到新文件的最佳方式。对不起,我知道的太少了。谢谢1。PowerShell数组比较不处理通配符。普通的逐项比较会处理通配符。2.您可以将数组分配给$979;.Split('.|')。$fields=$979;.Split('.|')。然后是字段[2]将获得第三个字段。但这将增加内存消耗。3.just use$file=get content Hi Dennis-谢谢。最后一件事是,$ref数组中的$ref | foreach{#项if($field-like$#){#用ref$refhit=$true$outline+=$.TrimEnd('*')+“|”在ref文件中找到匹配项后,我希望终止foreach并转到原始文件中的下一个字段。中断或继续似乎不起任何作用?在这种情况下,您需要使用foreach($array中的字段){…}而不是对数组使用管道。但管道通常要快得多:)没有办法中止管道中的一部分流(我认为该特性将在Posh7.1中可用)。