Преобразование не менее двух текстовых файлов с разными строками в один CSV-PowerShell - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь преобразовать два файла TXT в один файл CSV, используя скрипт powershell. Когда файлы имеют одинаковую структуру и одинаковое количество строк, дело выглядит легко. Но в моем случае txt-файлы имеют различную структуру.

Знак канала в обоих txt-файлах не является разделителем и должен рассматриваться как обычный символ, а это строка.

File URL.txt

L5020|http://linktosite.de|URL
L100|http://sitelink.de|URL
L50|http://abcde.de|URL
L511|http://bbcccddeee.de|URL
L300|http://link123456.de|URL
L5450|http://randomlink.de|URL_DE
L5460|http://randomwebsitelink.de|URL_DE

Файл URL1.txt

L5020|http://linktosite.de|URL|P555
L100|http://sitelink.de|URL|P523
L50|http://abcde.de|URL|P53
L511|http://bbcccddeee.de|URL|P540

CSV, который, как я ожидаю, должен выглядеть следующим образом, а разделитель - ";"

HEADER1;HEADER2
L5020|http://linktosite.de|URL;L5020|http://linktosite.de|URL|P555
L100|http://sitelink.de|URL;L100|http://sitelink.de|URL|P523
L50|http://abcde.de|URL;L50|http://abcde.de|URL|P53
L511|http://bbcccddeee.de|URL;L511|http://bbcccddeee.de|URL|P540
L300|http://link123456.de|URL;  
L5450|http://randomlink.de|URL_DE;  
L5460|http://randomwebsitelink.de|URL_DE;   

Я пытался что-то подобное

$URL = "C:\Users\XXX\Desktop\URL.txt"
$URLcontent = Get-Content $URL
$URL1 = "C:\Users\XXX\Desktop\URL1.txt"
$URLcontent1 = Get-Content $URL1

$results = @() # Empty array to store new created rows in
$csv = Import-CSV "C:\Users\XXX\Desktop\map.csv" -Delimiter ';'
foreach ($row in $csv) {
    $properties = [ordered]@{
        HEADER1   =  $URLcontent
        HEADER2    = $URLcontent1

          }
    # insert the new row as an object into the results-array
    $results += New-Object psobject -Property $properties
}
# foreach-loop filled the results-array - export it as a CSV-file
$results | Export-Csv "C:\Users\XXXX\Desktop\map_final.csv" -NoTypeInformation

И что-то в этом роде:

import-csv URL.txt -Header 'HEADER1' |  Export-CSV "C:\Users\xxx\Desktop\URL.csv"  -Delimiter ';' -NoTypeInformation 
import-csv URL1.txt  -Header 'HEADER2' | Export-CSV "C:\Users\xxx\Desktop\URL1.csv" -Delimiter ';' -NoTypeInformation  
Get-ChildItem "C:\Users\xx\Desktop" -Filter "URL*.csv" | Select-Object -ExpandProperty FullName | Import-Csv | Export-Csv .\combinedcsvs.csv -NoTypeInformation -Append

Без успеха ...

BR

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

На основании обновлений в вашем вопросе, если вы хотите что-то построить самостоятельно, вы, вероятно, захотите сделать что-то вроде этого:

$Url1 = @(Get-Content .\URL1.txt)
$i = 0
Get-Content .\URL.txt | Foreach-Object {
    [pscustomobject]@{
        HEADER1 = $_
        HEADER2 = If ($i -lt $URL1.Count) { $URL1[$i++] }
    }
} | Export-Csv .\combinedcsvs.csv -Delimiter ';' -NoTypeInformation -Append

В случае, если вы не хотите go из-за хлопот изобретать велосипед (со всеми подводными камнями, включая настройку производительности). Использование Join-Object Я упоминал в комментарии:

Import-Csv .\URL.txt -Header HEADER1 |
LeftJoin (Import-Csv .\URL1.txt -Header HEADER2) |
Export-Csv .\combinedcsvs.csv -Delimiter ';' -NoTypeInformation -Append
  • Примечание 1: Я не уверен, почему вы пытаетесь чтобы импортировать что-то вроде map.csv, я думаю, что это необходимо.
  • Примечание 2: Если вы все еще хотите go по-своему, попробуйте избегайте использования оператора увеличения (+ =) для создания коллекции это очень дорогой оператор.
  • Примечание 3: обычно это не Рекомендуется объединять строки в их индексе строк, поскольку список может не сортироваться или иметь дубликаты, поэтому лучше объединять списки по указанному свойству c, например Url:

Import-Csv .\URL.txt -Delimiter '|' -Header Lid,Url,Type |
LeftJoin (Import-Csv .\URL1.txt -Delimiter '|' -Header Lid2,Url,Type2,Pid) -On Url |
Format-Table # or: Export-Csv .\combinedcsvs.csv -Delimiter ';' -NoTypeInformation

Lid   Url                         Type   Lid2  Type2 Pid
---   ---                         ----   ----  ----- ---
L5020 http://linktosite.de        URL    L5020 URL   P555
L100  http://sitelink.de          URL    L100  URL   P523
L50   http://abcde.de             URL    L50   URL   P53
L511  http://bbcccddeee.de        URL    L511  URL   P540
L300  http://link123456.de        URL
L5450 http://randomlink.de        URL_DE
L5460 http://randomwebsitelink.de URL_DE

Или на все три (Lid, Url и Type) свойства:

Import-Csv .\URL.txt -Delimiter '|' -Header Lid,Url,Type |
LeftJoin (Import-Csv .\URL1.txt -Delimiter '|' -Header Lid,Url,Type,Pid) -On Lid,Url,Type |
Format-Table # or: Export-Csv .\combinedcsvs.csv -Delimiter ';' -NoTypeInformation

Lid   Url                         Type   Pid
---   ---                         ----   ---
L5020 http://linktosite.de        URL    P555
L100  http://sitelink.de          URL    P523
L50   http://abcde.de             URL    P53
L511  http://bbcccddeee.de        URL    P540
L300  http://link123456.de        URL
L5450 http://randomlink.de        URL_DE
L5460 http://randomwebsitelink.de URL_DE
0 голосов
/ 10 апреля 2020

Если вы хотите объединить только те строки, в которых оба файла содержат данные, вы можете сделать следующее:

$f1 = Get-Content file1.txt
$f2 = Get-Content file2.txt
$output = for ($i = 0; $i -lt [math]::Min($f1.count,$f2.count); $i++) {
   $f2[$i],$f1[$i] -join '|'
}
$output | Set-Content newfile.txt

Если вы хотите объединить все совпадающие строки и добавить дополнительные строки из одного из файлов, вы может сделать следующее:

$output = for ($i = 0; $i -lt [math]::Max($f1.count,$f2.count); $i++) {
    if ($f1[$i] -and $f2[$i]) {
        $f2[$i],$f1[$i] -join '|'
    } 
    else {
        $f2[$i],$f1[$i] | Where {$_}
    }
}
$output | Set-Content newfile.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...