1

私は、データベースに挿入する必要がある 1 日を通していくつかのファイルを生成する Linux サーバーを持っています。Puttyを使用して、SQL 2008を実行しているサーバーにそれらをsftpできます。問題はファイル自体の構造であり、異なる列に配置されるテキストの文字列がありますが、SQLへの一括挿入はそれをすべて入れようとします6 列ではなく 1 列に。Powershell は最良の方法ではないかもしれませんが、いくつかのサイトで、行末を見つけて置換または追加する方法を見てきました。数えて挿入できますか?

したがって、ファイルは次のようになります: '18240087A +17135555555 3333333333'、ここで 18、24、00、87、A は異なる列で、A と + の間に空白スペースがあります。これは文字数 10-19 です。別の列の場合、文字 20 ~ 30 は列、文字 31 ~ 36 は新しい列であるスペースなどです。だから私は「|」を挿入したい または ',' を使用して、SQL が列の終了位置を認識できるようにします。PowerShell がランダムにカウントすることは可能ですか?


これは、回答したすべての人に返信する方法ではない場合があります。事前にお詫び申し上げます。これは私にとって初めての PowerShell スクリプトであるため、皆様からのご意見をお待ちしております。これは、CDR レコードを生成している Avaya SIP サーバーです。後でレポートを作成するために、サーバーから取得して SQL に挿入する必要があります。エクスポートされたファイルは次のようになります。

10/15 18:47

18470214A +14434444444 3013777777 CME-SBC HHHH-CM 4 M00 0

最初は、最初の行を削除して、Kieranties の投稿から変更した出力に対してスクリプトを実行することを考えました。

$test = Get-Content 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*(.*)$"

if($test -match $pattern){ $result = $matches.Values | select -first ($matches.Count-1)

[array]::Reverse($result, 0, $result.Length)

$result = $result -join "|"    
$result | Out-File c:\Share\CDR\results1.txt

}

しかし、日付が含まれているため、最初の行が必要であることに気付きました。私はそれを別の方法で解決しようとすることができます。

また、次のように、ファイルに 2 行以上の CDR 情報が含まれている場合があることもわかりました。

10/15 18:24

18240087A +14434444444 3013777777 CME-SBC HRSA-CM 4 M00 0

18240096A +14434444445 3013777778 CME-SBC HRSA-CM 4 M00 0

私が作成した.ps1ファイルは2番目の文字列を与えないので、これを追加しようとしました:

foreach ($Data in $test) { $Data = $Data -split(',')

実行に失敗します。どうすれば複数の行 (およびおそらくその最初の行) を実行できますか? 役立つチュートリアルを知っている場合は、それも大歓迎です!

4

4 に答える 4

0

あなたの回答に基づいて回答を改善しました (実際の質問を更新してその情報を含めることをお勧めします!)

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 for Developersです。これは短く簡潔で、Powershell について正しい考え方で考えることができる素晴らしい情報でいっぱいです。

于 2012-10-16T14:22:27.433 に答える
0

私は分割規則を完全には守っていません。とにかく、どのようなソフトウェアがテキスト ファイルを書き込みますか? 構造を変えるように指示できるのではないでしょうか?

そうは言っても、パイプを挿入するのは簡単です.Insert()

$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

そこから、残りの行データの分割に進むことができます。

于 2012-10-16T12:17:03.743 に答える
0

これは方法です(本当に醜いIMO、もっとうまくできると思います):

$a = '18240087A +17135555555 3333333333'
$b = @( ($a[0..1] -join ''), ($a[2..3] -join ''), ($a[4..5] -join ''),
    ($a[6..7] -join ''), ($a[8] -join ''), ($A[10..19] -join ''),
    ($a[20..30] -join ''), ($a[31..36] -join ''))
$c = $b -join '|'
$c
18|24|00|87|A|+171355555|55 33333333|33

適切な分割が必要かどうかはわかりませんが、それぞれの値を変更することで、必要に[x..y]応じてより適切に行うことができます。文字配列は 0 から始まることに注意してください。最初の文字は 0 などです。

于 2012-10-16T11:55:20.707 に答える