2016-03-21 14 views
1

私たちのT &システムのソフトウェアを更新しました。これはタブ区切り形式のCSVファイルを生成します。給与計算ソフトウェアはセミコロンで区切られた古い形式でこれを必要とします。私は両方のベンダーと連絡を取り合っていて、いずれも他のベンダーに対応する方法がないので、CSVファイルを給与計算ソフトウェアに合わせて変換する必要があります。私は、混在した結果を持つPowerShellでこれをやろうとしました。タブ区切り記号をセミコロンに変換します

まず私は、タブ区切りを削除しますが;をしなかった

Import-Csv ".\desktop\new version.csv" -Delimiter `t | 
    Export-Csv ".\converted.csv" -NoTypeInf 

を試してみました。だから私は、その後だけヘッダに、;にタブ付きから、それを変換しました

Import-Csv ".\desktop\new version.csv" -Delimiter `t | 
    Export-Csv ".\desktop\converted.csv" -NoTypeInformation -Delimiter ";" 

を試してみました。残りのデータは完全に無視されました。私は、別のアプローチを試み、正しくファイルをフォーマット

$path = ".\desktop\new.csv" 
$outPath = ".\desktop\converted.csv" 
Get-Content -path $path | 
    ForEach-Object {$_ -replace "`t",";" } | 
    Out-File -filepath $outPath 

を使用するが、データの各列の間に余分な空白行を置きます。私は何が間違っているのか分からない!

+1

入力したTSVの形式が間違っていない限り、2番目のコマンドはうまくいきました。 –

答えて

0

ここは、私がやっているようにテキストファイルの文字列を置き換えるために使用した関数です。これは、テキストファイルの中にカラムを区切るタブ以外のタブがないことを前提としています。私はないと仮定しています。

Find-InTextFile -FilePath C:\MyFile.csv -Find "`t" -Replace ';' 

function Find-InTextFile 
{ 
    <# 
    .SYNOPSIS 
     Performs a find (or replace) on a string in a text file or files. 
    .EXAMPLE 
     PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine' 

     Replaces all instances of the string 'water' into the string 'wine' in 
     'C:\MyFile.txt'. 
    .EXAMPLE 
     PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' 

     Finds all instances of the string 'water' in the file 'C:\MyFile.txt'. 
    .PARAMETER FilePath 
     The file path of the text file you'd like to perform a find/replace on. 
    .PARAMETER Find 
     The string you'd like to replace. 
    .PARAMETER Replace 
     The string you'd like to replace your 'Find' string with. 
    .PARAMETER UseRegex 
     Use this switch parameter if you're finding strings using regex else the Find string will 
     be escaped from regex characters 
    .PARAMETER NewFilePath 
     If a new file with the replaced the string needs to be created instead of replacing 
     the contents of the existing file use this param to create a new file. 
    .PARAMETER Force 
     If the NewFilePath param is used using this param will overwrite any file that 
     exists in NewFilePath. 
    #> 
    [CmdletBinding(DefaultParameterSetName = 'NewFile')] 
    param (
     [Parameter(Mandatory = $true)] 
     [ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })] 
     [string[]]$FilePath, 

     [Parameter(Mandatory = $true)] 
     [string]$Find, 

     [Parameter()] 
     [string]$Replace, 

     [Parameter()] 
     [switch]$UseRegex, 

     [Parameter(ParameterSetName = 'NewFile')] 
     [ValidateScript({ Test-Path -Path ($_ | Split-Path -Parent) -PathType 'Container' })] 
     [string]$NewFilePath, 

     [Parameter(ParameterSetName = 'NewFile')] 
     [switch]$Force 
    ) 
    begin 
    { 
     if (!$UseRegex.IsPresent) 
     { 
      $Find = [regex]::Escape($Find) 
     } 
    } 
    process 
    { 
     try 
     { 
      foreach ($File in $FilePath) 
      { 
       if ($Replace) 
       { 
        if ($NewFilePath) 
        { 
         if ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and $Force.IsPresent) 
         { 
          Remove-Item -Path $NewFilePath -Force 
          (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force 
         } 
         elseif ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and !$Force.IsPresent) 
         { 
          Write-Warning "The file at '$NewFilePath' already exists and the -Force param was not used" 
         } 
         else 
         { 
          (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force 
         } 
        } 
        else 
        { 
         (Get-Content $File) -replace $Find, $Replace | Add-Content -Path "$File.tmp" -Force 
         Remove-Item -Path $File 
         Rename-Item -Path "$File.tmp" -NewName $File 
        } 
       } 
       else 
       { 
        Select-String -Path $File -Pattern $Find 
       } 
      } 
     } 
     catch 
     { 
      Write-Error -Message $_.Exception.Message 
     } 
    } 
} 
3

最後の例でエンコードの問題が発生していると思いますが、 Get-ContentはAsciiとして読み込み、Out-FileはデフォルトでUnicodeになります。 をOut-Fileに設定するか、Set-Contentを使用してください。

必要に応じてこれを少し下げて調整することもできます。しかし、あなたの第二のコード例

(Get-Content -path $path) -replace "`t",";" | Set-Content -filepath $outPath 

...

Import-Csv ".\desktop\new version.csv" -Delimiter `t | Export-Csv ".\desktop\converted.csv" -NoTypeInformation -Delimiter ";" 

はセミコロンにタブを交換するにうまく働いているはずです。それが動作していない場合、あなたのソースデータに問題があると思います。コード上記後続列を作成されたコメントに基づいて、ソースファイル

について


。その可能性が高い原因は、変換されている各行の末尾のタブです。そうであれば、もう少し操作する必要があります。この場合、ループはforeachループを使用する方が簡単です。

Get-Content -path $path | 
ForEach-Object {$_.Trim() -replace "`t",";" } | 
Set-Content -filepath $outPath 

これは、各行の最後のタブ/空白を削除します。このようにしている可能性があります大きな注意点です。私は最後に空の列があるとデータを削除する可能性があると思います。しかし、それらの列が既に空であった場合、ヘッダが整形され、入力プログラムがこれを考慮することができる限り重要ではありません。それ以外の場合は、Import-CSVでファイルを読み込み、最後の列を削除します。

+0

こんにちは、ありがとう、私はそれらを疲れて、彼らは仕事をしますが、私は元のCSVファイルはいくつかの書式設定/データの問題を抱えていると思いますので空のデータの余分な行を追加します。 – SimonH

+0

@SimonHソースデータに後続のタブがありますか? – Matt

+0

私はどこにいなければなりません! csvを生成するソフトウェアは最高ではないので、ファイルを作成する方法にバグが存在する可能性は非常に高いです。助けてくれてありがとう。 – SimonH

関連する問題