Отфильтруйте несколько CSV для текста и создайте новые файлы - PullRequest
0 голосов
/ 29 мая 2020

У меня около 2500 файлов CSV, каждый размером около 20 МБ. Я пытаюсь отфильтровать определенные строки из каждого файла и сохранить их в новом файле.

Итак, если у меня есть:

File 1 :
    Row1
    Row2
    Row3
File 2 : 
    Row2
    Row3 
and so on..

Если я фильтрую для всех файлов и выбираю «Row2» "в качестве текста фильтра в новой папке должны быть все файлы только со строками, соответствующими тексту фильтра.

Просматривая некоторые форумы, я придумал следующее, что может помочь мне фильтровать строки, но я не уверен, как это сделать рекурсивно, плюс я также не знаю, достаточно ли это быстрый метод . Любая помощь приветствуется.

Get-Content "C:\Path to file" | Where{$_ -match "Rowfiltertext*"} | Out-File "Path to Out file"

Я использую windows, поэтому я думаю, что решение типа Powershell здесь будет лучшим.

Текст, который нужно отфильтровать, всегда будет в первом столбце.

Спасибо, Сиддхант

Ответы [ 2 ]

0 голосов
/ 30 мая 2020

Вот два быстрых способа поиска строки внутри (текстовых) файлов:

1) с помощью переключателя

$searchPattern = [regex]::Escape('Rowfiltertext')  # for safety escape regex special characters
$sourcePath    = 'X:\Path\To\The\Csv\Files'
$outputPath    = 'X:\FilteredCsv.txt'

# if you also need to search inside subfolders, append -Recurse to the Get-ChildItem cmdlet
Get-ChildItem -Path $sourcePath -Filter '*.csv' -File | ForEach-Object {
    # iterate through the lines in the file and output the ones that match the search pattern
    switch -Regex -File $_.FullName {
        $searchPattern { $_ }
    }
} | Set-Content -Path $outputPath  # add -PassThru to also show on screen

2) с помощью Select -String

$searchPattern = [regex]::Escape('Rowfiltertext')  # for safety escape regex special characters
$sourcePath    = 'X:\Path\To\The\Csv\Files'
$outputPath    = 'X:\FilteredCsv.txt'

# if you also need to search inside subfolders, append -Recurse to the Get-ChildItem cmdlet
Get-ChildItem  -Path $sourcePath -Filter '*.csv' -File | ForEach-Object {
    ($_ | Select-String -Pattern $searchPattern).Line
} | Set-Content -Path $outputPath  # add -PassThru to also show on screen

Если вы хотите вывести новый файл csv для каждого исходного файла,

используйте:

3 ) с помощью переключателя

$searchPattern = [regex]::Escape('Rowfiltertext')  # for safety escape regex special characters
$sourcePath    = 'X:\Path\To\The\Csv\Files'
$outputPath    = 'X:\FilteredCsv'

if (!(Test-Path -Path $outputPath -PathType Container)) {
    $null = New-Item -Path $outputPath -ItemType Directory
}

# if you also need to search inside subfolders, append -Recurse to the Get-ChildItem cmdlet
(Get-ChildItem -Path $sourcePath -Filter '*.csv' -File) | ForEach-Object {
    # create a full target filename for the filtered output csv
    $outFile = Join-Path -Path $outputPath -ChildPath ('New_{0}' -f $_.Name)
    # iterate through the lines in the file and output the ones that match the search pattern
    $result = switch -Regex -File $_.FullName {
        $searchPattern { $_ }
    }
    $result | Set-Content -Path $outFile  # add -PassThru to also show on screen
}

4) с помощью Select-String

$searchPattern = [regex]::Escape('Rowfiltertext')  # for safety escape regex special characters
$sourcePath    = 'X:\Path\To\The\Csv\Files'
$outputPath    = 'X:\FilteredCsv'

# if you also need to search inside subfolders, append -Recurse to the Get-ChildItem cmdlet
(Get-ChildItem  -Path $sourcePath -Filter '*.csv' -File) | ForEach-Object {
    # create a full target filename for the filtered output csv
    $outFile = Join-Path -Path $outputPath -ChildPath ('New_{0}' -f $_.Name)
    ($_ | Select-String -Pattern $searchPattern).Line | Set-Content -Path $outFile  # add -PassThru to also show on screen
}

Надеюсь, что это поможет

0 голосов
/ 29 мая 2020

Re. «достаточно быстрый метод»:
Get-Content работает очень медленно. Вместо этого вы можете использовать "System.IO.StreamReader", т.е. прочитать полное содержимое файла в строке, затем разделить эту строку на строки и так далее, например:

[System.IO.FileStream]$objFileStream = New-Object System.IO.FileStream($Csv.FullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
[System.IO.StreamReader]$objStreamReader = New-Object System.IO.StreamReader($objFileStream, [System.Text.Encoding]::UTF8)
$strFileContent = ($objStreamReader.ReadToEnd())
$objStreamReader.Close()
$objStreamReader.Dispose()
$objFileStream.Close()
$objFileStream.Dispose()

[string[]]$arrFileContent = $strFileContent -split("`r`n")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...