对字符串中的字符进行计数,然后使用PowerShell插入分隔符

对字符串中的字符进行计数,然后使用PowerShell插入分隔符,powershell,Powershell,我有一个linux服务器,它会整天生成几个需要插入数据库的文件;使用Putty,我可以将它们发送到运行SQL 2008的服务器上。问题是文件本身的结构,它有一个文本字符串,要放在不同的列中,但sql中的大容量插入尝试将所有文本放在一列而不是六列中。Powershell可能不是最好的方法,但我在几个网站上看到过它如何查找、替换或追加到行的末尾,它可以计数和插入吗 所以文件看起来是这样的:'18240087A+1713555555 3333333',其中18,24,00,87,A是不同的列,那么A和

我有一个linux服务器,它会整天生成几个需要插入数据库的文件;使用Putty,我可以将它们发送到运行SQL 2008的服务器上。问题是文件本身的结构,它有一个文本字符串,要放在不同的列中,但sql中的大容量插入尝试将所有文本放在一列而不是六列中。Powershell可能不是最好的方法,但我在几个网站上看到过它如何查找、替换或追加到行的末尾,它可以计数和插入吗

所以文件看起来是这样的:'18240087A+1713555555 3333333',其中18,24,00,87,A是不同的列,那么A和+之间有一个空格,即字符计数10-19,这是另一列,字符20-30是一列,字符31-36是一个空格,这是新列,依此类推。因此,我想插入一个“|”或一个“,”,以便sql了解列的结束位置。PowerShell是否可以随机计数


这可能不是回应所有回答者的方式,我提前道歉。由于这是我的第一个PowerShell脚本,我非常感谢各位的投入。这是一个Avaya SIP服务器,它正在生成CDR记录,我必须从服务器中提取这些记录并将其插入到SQL中以备以后的报告。导出的文件如下所示:

2015年10月18:47

18470214A+144344444 301377777 CME-SBC HHHH-CM 4 M00 0

起初,我只是想删除第一行并对输出运行一个脚本,我在Kieranties post中对其进行了修改:

$test=获取内容C:\Share\CDR\testCDR.txt

$pattern=“^({2})({2})({1})({2})({1})({1})\s*({15})({10})\s*({7})\s*({7})\s*({1})\s*({1})({1})({1})\s*(.*$”

如果($test-match$pattern){ $result=$matches.Values |选择-first($matches.Count-1)

}

但后来我意识到我需要第一行,因为它包含日期。不过我可以试着用另一种方法来解决这个问题

我现在还看到,有时文件包含2行或多行CDR信息,例如:

2015年10月18:24

18240087A+144344444 301377777 CME-SBC HRSA-CM 4 M00 0

18240096A+144344445 301377778 CME-SBC HRSA-CM 4 M00 0

而我创建的.ps1文件没有给出第二个字符串,因此我尝试添加以下内容:

foreach($test中的数据) { $Data=$Data-split(','))

但它无法运行。我如何才能完成多行(可能是第一行)?如果您知道有一个教程可以提供帮助,那也非常感谢!

这是一种方法(在我看来,我认为它可以做得更好):

我不知道这是否是您需要的第三个拆分,但是更改每个
[x..y]
中的值可以更好地满足您的需要。请记住,字符数组是基于0的,然后第一个字符是0,依此类推。

这是一种方法(在我看来,它可以做得更好):


我不知道这是否是您需要的正确拆分,但是更改每个
[x..y]中的值
您可以做更适合您需要的事情。请记住字符数组是基于0的,然后第一个字符是0,依此类推。

我不太遵守拆分规则。到底是什么样的软件编写文本文件?也许可以指示它更改结构

也就是说,使用
.Insert()


从那里,您可以继续拆分其余的行数据。

我不太遵守拆分规则。到底是哪种软件编写文本文件?也许可以指示它更改结构

也就是说,使用
.Insert()


从这里开始,您可以继续分割行数据的其余部分。

我根据您的回答改进了我的答案(注意,您最好更新实际问题以包含该信息!)

Powershell中的
Get Content
的好处在于,它将内容作为一个拆分为行尾字符的数组返回。再加上允许从一个数组中进行多个赋值,您将得到一些整洁的代码

下面有一个函数,可以根据修改后的原始答案处理每一行,然后用一个处理文件的函数包装

它读取给定的文件,将第一行设置为
$date
,将其余内容设置为
$content
。然后创建一个输出文件,将日期添加到输出中,然后在其余内容上循环执行正则表达式检查,如果检查成功,则添加内容的解析版本

Function Parse-CDRFileLine {
    Param(
        [string]$line
    )

    $pattern = "^(.{2})(.{2})(.{1})(.{2})(.{1})(.{1})\s*(.{15})(.{10})\s*(.{7})\s*(.{7})\s*(.{1})\s*(.{1})(.{1})(.{1})\s*(.*)$"
    if($line -match $pattern){ 
        $result = $matches.Values | select -first ($matches.Count-1)
        [array]::Reverse($result, 0, $result.Length)
        $result = $result -join "|"    
        $result
    }
}



Function Parse-CDRFile{
    Param(
        [string]$filepath
    )    

    # Read content, setting first line to $date, the rest to $content
    $date,$content = Get-Content $filepath    

    # Create the output file, overwrite if neccessary
    $outputFile = New-Item "$filepath.out" -ItemType file -Force

    # Add the date line
    Set-Content $outputFile $date

    # Process the rest of the content
    $content | 
        ? { -not([string]::IsNullOrEmpty($_)) } |
        % { Add-Content $outputFile (Parse-CDRFileLine $_) }
}

Parse-CDRFile "C:\input.txt"
我使用了您的示例输入,得到的结果是:

18:24 10/15
18|24|0|08|7|A|+14434444444 30|13777777 C|ME-SBC |HRSA-CM|4|M|0|0|0
18|24|0|09|6|A|+14434444445 30|13777778 C|ME-SBC |HRSA-CM|4|M|0|0|0

这里有大量的资源,但我特别建议道格拉斯·芬克斯(Douglas Finkes)使用Powershell,它简短、简洁,而且信息丰富,可以让您以正确的思维方式思考问题。我根据您的回答改进了我的答案(请注意,您最好更新实际问题以包含该信息!)

Powershell中的
Get Content
的好处在于,它将内容作为一个拆分为行尾字符的数组返回。再加上允许从一个数组中进行多个赋值,您将得到一些整洁的代码

下面有一个函数,可以根据修改后的原始答案处理每一行,然后用一个处理文件的函数包装

它读取给定的文件,将第一行设置为
$date
,将其余内容设置为
$content
。然后创建一个输出文件,将日期添加到输出中,然后在其余内容上循环执行正则表达式检查,并在出现错误时添加内容的解析版本
$a= '18240087A +17135555555 3333333333'
$a.Substring(0, $a.IndexOf('+')).Insert(2, '|').insert(5,'|').insert(8, '|').insert(11, '|').insert(13, '|')
# Output: 18|24|00|87|A|

# Rest of the line:
$a.Substring($a.IndexOf('+')+1)
# Output: 17135555555 3333333333
Function Parse-CDRFileLine {
    Param(
        [string]$line
    )

    $pattern = "^(.{2})(.{2})(.{1})(.{2})(.{1})(.{1})\s*(.{15})(.{10})\s*(.{7})\s*(.{7})\s*(.{1})\s*(.{1})(.{1})(.{1})\s*(.*)$"
    if($line -match $pattern){ 
        $result = $matches.Values | select -first ($matches.Count-1)
        [array]::Reverse($result, 0, $result.Length)
        $result = $result -join "|"    
        $result
    }
}



Function Parse-CDRFile{
    Param(
        [string]$filepath
    )    

    # Read content, setting first line to $date, the rest to $content
    $date,$content = Get-Content $filepath    

    # Create the output file, overwrite if neccessary
    $outputFile = New-Item "$filepath.out" -ItemType file -Force

    # Add the date line
    Set-Content $outputFile $date

    # Process the rest of the content
    $content | 
        ? { -not([string]::IsNullOrEmpty($_)) } |
        % { Add-Content $outputFile (Parse-CDRFileLine $_) }
}

Parse-CDRFile "C:\input.txt"
18:24 10/15
18|24|0|08|7|A|+14434444444 30|13777777 C|ME-SBC |HRSA-CM|4|M|0|0|0
18|24|0|09|6|A|+14434444445 30|13777778 C|ME-SBC |HRSA-CM|4|M|0|0|0