Как удалить все кавычки в файле csv с помощью сценария powershell? - PullRequest
2 голосов
/ 14 марта 2020

Я хотел бы удалить все символы кавычек в моем экспортированном файле CSV, это очень раздражает, когда я сгенерировал новый файл CSV, и мне нужно вручную удалить все цитаты, которые включены в строку. Может ли кто-нибудь предоставить мне скрипт Powershell для решения этой проблемы? Спасибо.

$File = "c:\programfiles\programx\file.csv"
(Get-Content $File) | Foreach-Object {
    $_ -replace """, ""
} | Set-Content $File

Ответы [ 8 ]

4 голосов
/ 14 марта 2020

В следующий раз, когда вы сделаете это, у export-csv в powershell 7 появится новая опция, которая может вам понравиться:

export-csv -UseQuotes AsNeeded
3 голосов
/ 14 марта 2020

Кажется, многие из нас уже объяснили, что кавычки иногда необходимы в файлах CSV. Это тот случай, когда:

  • значение содержит двойную кавычку
  • значение содержит символ разделителя
  • значение содержит символы новой строки или пробел в начале или конец строки

В PS версии 7 у вас есть возможность использовать параметр -UseQuotes AsNeeded. Для более старых версий я сделал эту вспомогательную функцию для преобразования в CSV, используя при необходимости только кавычки:

function ConvertTo-CsvNoQuotes {
    # returns a csv delimited string array with values unquoted unless needed
    [OutputType('System.Object[]')]
    [CmdletBinding(DefaultParameterSetName = 'ByDelimiter')]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        [PSObject]$InputObject,

        [Parameter(Position = 1, ParameterSetName = 'ByDelimiter')]
        [char]$Delimiter = ',',

        [Parameter(ParameterSetName = 'ByCulture')]
        [switch]$UseCulture,
        [switch]$NoHeaders,
        [switch]$IncludeTypeInformation  # by default, this function does NOT include type information
    )
    begin {
        if ($UseCulture) { $Delimiter = (Get-Culture).TextInfo.ListSeparator }
        # regex to test if a string contains a double quote, the delimiter character,
        # newlines or has whitespace at the beginning or the end of the string.
        # if that is the case, the value needs to be quoted.
        $needQuotes = '^\s|["{0}\r\n]|\s$' -f [regex]::Escape($Delimiter)
        # a boolean to check if we have output the headers or not from the object(s)
        # and another to check if we have output type information or not
        $doneHeaders = $doneTypeInfo = $false
    }

    process {
        foreach($item in $InputObject) {
            if (!$doneTypeInfo -and $IncludeTypeInformation) {
                '#TYPE {0}' -f $item.GetType().FullName
                $doneTypeInfo = $true
            }
            if (!$doneHeaders -and !$NoHeaders) {
                $row = $item.PsObject.Properties | ForEach-Object {
                    # if needed, wrap the value in quotes and double any quotes inside
                    if ($_.Name -match $needQuotes) { '"{0}"' -f ($_.Name -replace '"', '""') } else { $_.Name }
                }
                $row -join $Delimiter
                $doneHeaders = $true
            }
            $item | ForEach-Object {
                $row = $_.PsObject.Properties | ForEach-Object {
                    # if needed, wrap the value in quotes and double any quotes inside
                    if ($_.Value -match $needQuotes) { '"{0}"' -f ($_.Value -replace '"', '""') } else { $_.Value }
                }
                $row -join $Delimiter
            }
        }
    }
}

Используя ваш пример, удалите ненужные кавычки в существующем файле CSV:

$File = "c:\programfiles\programx\file.csv"
(Import-Csv $File) | ConvertTo-CsvNoQuotes | Set-Content $File
3 голосов
/ 14 марта 2020

с учетом того, что это может привести к sh вашим данным, если вы добавили в них двойные кавычки, вот еще один вариант идеи ... [ ухмылка ]

что он делает ...

  • определяет полные имена файлов ввода и вывода
  • получает файлы *.tmp из фильтров temp dir
  • для 1-го три файла и только три базовых c свойства
  • создает файл для работы с
  • загружает содержимое файла
  • заменяет двойные кавычки ничем
  • сохраняет очищенный файл во 2-е имя файла
  • отображает исходную и очищенную версии файла

код ...

$TestCSV = "$env:TEMP\Ted.Xiong_-_Test.csv"
$CleanedTestCSV = $TestCSV -replace 'Test', 'CleanedTest'

Get-ChildItem -LiteralPath $env:TEMP -Filter '*.tmp' -File |
    Select-Object -Property Name, LastWriteTime, Length -First 3 |
    Export-Csv -LiteralPath $TestCSV -NoTypeInformation

(Get-Content -LiteralPath $TestCSV) -replace '"', '' |
    Set-Content -LiteralPath $CleanedTestCSV

Get-Content -LiteralPath $TestCSV
'=' * 30
Get-Content -LiteralPath $CleanedTestCSV

вывод .. .

"Name","LastWriteTime","Length"
"hd4130E.tmp","2020-03-13 5:23:06 PM","0"
"hd418D4.tmp","2020-03-12 11:47:59 PM","0"
"hd41F7D.tmp","2020-03-13 5:23:09 PM","0"
==============================
Name,LastWriteTime,Length
hd4130E.tmp,2020-03-13 5:23:06 PM,0
hd418D4.tmp,2020-03-12 11:47:59 PM,0
hd41F7D.tmp,2020-03-13 5:23:09 PM,0
1 голос
/ 14 марта 2020

Дополнительная двойная кавычка может использоваться для экранирования двойной кавычки в строке:

$File = "c:\programfiles\programx\file.csv" 
(Get-Content $File) | Foreach-Object { $_ -replace """", "" } | Set-Content $File
1 голос
/ 14 марта 2020

Одно решение для удаления двойных кавычек в строку в кавычках:

$delimiter=","
$InputFile="c:\programfiles\programx\file.csv"
$OutputFile="c:\programfiles\programx\resultfile.csv"

#import file in variable (not necessary if your faile is big repeat this import where i use $ContentFile)
$ContentFile=import-csv $InputFile -Delimiter $delimiter -Encoding utf8 

#list of property of csv file
$properties=($ContentFile | select -First 1 | Get-Member -MemberType NoteProperty).Name


#write header into new file
$properties -join $delimiter | Out-File $OutputFile -Encoding utf8

#write data into new file
$ContentFile | %{
$RowObject=$_                                        #==> get row object
$Line=@()                                            #==> create array
$properties | %{$Line+=$RowObject."$_"}              #==> Loop on every property, take value (without quote) inot row object
$Line -join $delimiter                               #==> join array for get line with delimer and send to standard outut 
} | Out-File $OutputFile -Encoding utf8 -Append      #==> export result to output file
1 голос
/ 14 марта 2020

После того, как вы экспортировали файл CSV с помощью Export-CSV, вы можете использовать Get-Content, чтобы загрузить файл CSV в массив строк, затем использовать Set-Content и replace для удаления кавычек:

Set-Content -Path sample.csv -Value ((Get-Content -Path sample.csv) -replace '"')

Как подсказывает mklement0 , это может привести к повреждению CSV, если некоторые строки будут заключены в кавычки. Это решение просто просматривает весь файл и заменяет каждую цитату на ''.

Вы также можете ускорить это с помощью переключателя -Raw с Get-Content, который возвращает целую строку с сохраненными символами новой строки вместо массива строк с разделителями новой строки:

Set-Content -NoNewline -Path sample.csv -Value ((Get-Content -Raw -Path sample.csv) -replace '"')
1 голос
/ 14 марта 2020

Как и выше, кавычки действительны для csv, но для их удаления необходимо экранировать кавычку в операции замены, как специальный символ:

$File = "c:\programfiles\programx\file.csv"
(Get-Content $File) | Foreach-Object {
    $_ -replace "`"", ""
} | Set-Content $File
1 голос
/ 14 марта 2020

Почему вы вручную в текстовом редакторе читаете CSV-файлы?

Вы экспортировали их в этот формат по причине. Чтобы прочитать их, просто импортируйте их обратно и просмотрите их на экране и / или прочитайте их обратно и отправьте показания в блокнот для чтения.

Export-Csv -Path D:\temp\book1.csv
Import-Csv -Path D:\temp\book1.csv | 
Clip | 
Notepad # then press crtl+v, then save the notepad file with a new name.

Если вы не хотите использовать CSV, то не экспортировать как Csv, просто вывести в виде плоского файла, используя вместо него Out-File.

Обновление

Поскольку ваш последний комментарий для меня указан ваш последний вариант использования. CSV в SQL - очень распространенная вещь. Быстрый поиск в Интернете покажет вам, как даже предоставить вам скрипт. Вам также следует обратить внимание на модуль PowerShell DBATools.

Как импортировать данные из. csv в SQL Сервер, использующий PowerShell?

Импорт файлов CSV в БД Microsoft SQL с использованием PowerShell

Импорт CSVsIntoSQLv1.zip

Четыре простых способа импорта файлов CSV на SQL Сервер с PowerShell

Find-Module -Name '*dba*' 
<#
Version  Name         Repository Description
-------  ----         ---------- -----------
1.0.101  dbatools     PSGallery  The community module that enables SQL Server Pros to automate database development and server administration
...
#>

Обновление

Вы имеете в виду это ...

Get-Content 'D:\temp\book1.csv'
<#
# Results

"Site","Dept"
"Main","aaa,bbb,ccc"
"Branch1","ddd,eee,fff"
"Branch2","ggg,hhh,iii"
#>

Get-ChildItem -Path  'D:\temp' -Filter 'book1.csv' | 
ForEach {
    $NewFile = New-Item -Path 'D:\Temp' -Name "$($PSItem.BaseName).txt"
    Get-Content -Path $PSItem.FullName |
    ForEach-Object {
        Add-Content -Path $NewFile -Value ($PSItem -replace '"') -WhatIf
    }
}

<#
What if: Performing the operation "Add Content" on target "Path: D:\Temp\book1.txt".
What if: Performing the operation "Add Content" on target "Path: D:\Temp\book1.txt".
What if: Performing the operation "Add Content" on target "Path: D:\Temp\book1.txt".
What if: Performing the operation "Add Content" on target "Path: D:\Temp\book1.txt"
#>

Get-ChildItem -Path  'D:\temp' -Filter 'book1.csv' | 
ForEach {
    $NewFile = New-Item -Path 'D:\Temp' -Name "$($PSItem.BaseName).txt"
    Get-Content -Path $PSItem.FullName |
    ForEach-Object {
        Add-Content -Path $NewFile -Value ($PSItem -replace '"')
    }
}

Get-Content 'D:\temp\book1.txt'
<#
# Results

Site,Dept
Main,aaa,bbb,ccc
Branch1,ddd,eee,fff
Branch2,ggg,hhh,iii
#>

Конечно, вам нужно использовать подстановочный знак для файлов csv и использовать -Resurse, чтобы получить все каталоги и обработчик ошибок для убедитесь, что у вас нет конфликтов имен файлов.

...