Powershell提高了性能和编码效率,可将文本抓取并输出到文件

时间:2019-02-02 19:52:36

标签: powershell validation parsing

第一次编写PS脚本。该源应该是符合某些约束的管道分隔数据。该脚本用于识别源中违反某些规则的记录。我主要使用微软文档以了解足以让我到这一点。

问题:

  1. 是否有替代品改成readlines,出文件,或者我已经结构化的foreach循环这将非常大的文件执行更好的办法(〜几十GB的)?
  2. 是否可以将代码存储在数组/函数/中?为了以后访问它并使用一个参数执行它。例如,而不是写逻辑为每行的正则表达式或字符串长度相比,也许它接受一个字符串和一个lenght字符串长度的函数,不评价和通过或失败?
  3. 如何确定的最低版本为我使用的各种cmdlet的?
  4. 是否存在现有的cmdlet可以处理我本机尝试执行的验证类型?

谢谢

$record=''
$ary=''
$Nrecord=0
foreach ($record in [System.IO.File]::ReadLines("..."))
{
$results=''
$Nrecord++
$ary=$record.split('|')
if(($ary[0])    -and ($ary[0].length -gt 50))       {$results=$results + "$Nrecord|1|A|String length`r"} 
if(($ary[1])    -and ($ary[1].length -gt 50))       {$results=$results + "$Nrecord|2|A|String length`r"}
if(($ary[2])    -and ($ary[2] -notmatch "^[012]{1}$"))  {$results=$results + "$Nrecord|3|B|Category`r"}
if(($ary[4])    -and ($ary[4] -notmatch "^[0-9]{2}$"))  {$results=$results + "$Nrecord|5|B|Category`r"}
if(($ary[5])    -and ($ary[5] -notmatch "^[123]{1}$"))  {$results=$results + "$Nrecord|6|B|Category`r"}
if(($ary[6])    -and ($ary[6].length -gt 10))       {$results=$results + "$Nrecord|7|A|String length`r"}
if(($ary[7])    -and ($ary[7] -notmatch "^[0-9]{8}$"))  {$results=$results + "$Nrecord|8|C|Date`r"}
if(($ary[8])    -and ($ary[8] -notmatch "^[0-9]{8}$"))  {$results=$results + "$Nrecord|9|C|Date`r"}
if(($ary[9])    -and ($ary[9] -notmatch "^.{2}$"))  {$results=$results + "$Nrecord|10|B|Category`r"}
if(($ary[10])   -and ($ary[10] -notmatch "^.{2}$"))     {$results=$results + "$Nrecord|11|B|Category`r"}
if(($ary[11])   -and ($ary[11] -notmatch "^.{2}$"))     {$results=$results + "$Nrecord|12|B|Category`r"}
if(($ary[12])   -and ($ary[12] -notmatch "^.{2}$"))     {$results=$results + "$Nrecord|13|A|Category`r"}
if(($ary[13])   -and ($ary[13].length -gt 10))      {$results=$results + "$Nrecord|14|A|String length`r"}
if(($ary[14])   -and ($ary[14].length -gt 10))      {$results=$results + "$Nrecord|15|A|String length`r"}
if(($ary[16])   -and ($ary[16].length -gt 10))      {$results=$results + "$Nrecord|17|A|String length`r"}
if(($ary[18])   -and ($ary[17].length -gt 4))       {$results=$results + "$Nrecord|19|A|String length`r"}
if(($ary[26])   -and ($ary[26].length -gt 10))      {$results=$results + "$Nrecord|27|A|String length`r"}
if(($ary[27])   -and ($ary[27].length -gt 10))      {$results=$results + "$Nrecord|28|A|String length`r"}
if(($ary[29])   -and ($ary[29].length -gt 10))      {$results=$results + "$Nrecord|30|A|String length`r"}
if(($ary[30])   -and ($ary[30] -notmatch "^[01]{1}$"))  {$results=$results + "$Nrecord|31|B|Category`r"}
$results.TrimEnd("`r") | out-file -filepath "..." -append
}

2 个答案:

答案 0 :(得分:0)

假设您有一个名为sample.csv的CSV文件,其外观如下:

1,lori renier,shark
2,marc cuban,shark
3,adam,tuna
4,Olaf,Chubb

我将用类似...的数据加载数据。

$contents = Import-CSV -Path .\sample.csv -Delimiter ',' -Header @('id','name','type')

然后我将遍历内容进行所需的任何清洁工作...

foreach ($record in $contents) {
    if ($record.id.length -eq '') { $record.id = ... }
    if ($record.name -eq '') { $record.name = ... }
    if ($record.type -eq '') { $record.type = ... }
}

然后我将导出干净的结果...

Export-CSV -Path .\clean.csv -Delimiter ',' -Encoding 'ASCII' -NoTypeInformation -Append

.NET方法/对象通常更快。因此,使用[System.IO.File]::ReadLines("...")可能会更好一些,但是Powershell人士通常会先偏向可用的Commandlet,然后再使用.NET代码。

答案 1 :(得分:0)

我不知道这是否会帮助你很多,但你可以创建两个小测试功能,在一定程度上简化代码。另外,我认为使用Stringbuilder对象比执行许多字符串连接(commands : CommandModel[]; constructor(){} ngOnInit(){ this.commands = [ {buttonOption:{cssClass:'e-flat' , iconCss:'e-icons e-access' , click:this.onClick.bind(this)}}, //other buttons ] } )要好得多。

$results=$results + ...