Заменить строку на другую с определенным номером строки в текстовом файле - Powershell

Я уже видел какой-то пост, чтобы сделать это, но у меня не получилось. Я хотел бы заменить строку на другую с определенным номером строки в файле txt/csv.

У меня есть один файл (который должен обновить второй с новой датой)

"field1","date1","date2"
****,23/01/2018,03/04/2018
****,22/01/2018,03/04/2018

Второй (который должен быть старше):

"field1","date1","date2"
****,20/01/2018,03/04/2018
****,20/01/2018,03/04/2018

Мой скрипт выполняет следующие действия: запрашивает у пользователя файл, который будет использоваться для обновления второго запрашиваемого файла. Так что, если между некоторыми полями двух файлов есть совпадение строк, я бы хотел обновить "date1" на "date1" первого файла.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")


function Select-FileDialog
{
    param([string]$Title,[string]$Directory,[string]$Filter="CSV File (*.csv)|*.csv")
    [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
    $objForm = New-Object System.Windows.Forms.OpenFileDialog
    $objForm.InitialDirectory = $Directory
    $objForm.Filter = $Filter
    $objForm.Title = $Title
    $Show = $objForm.ShowDialog()
    If ($Show -eq "OK")
    {
        Return $objForm.FileName
    }
    Else
    {
        Write-Error "Operation cancelled by user."
    }
}
##Définition des variables
$ErrorActionPreference = "SilentlyContinue"
$dir = split-path -parent $MyInvocation.MyCommand.Definition
$base_file = Select-FileDialog -Title "Select a file" -Directory "$dir"
$bkp_file = "$dir\base.csv.bak"
##Make a backup of initial file
Copy-Item -Path "$final_file" -Destination "$bkp_file"
$final_file = Select-FileDialog -Title "Select a file" -Directory "$dir"
$import = Import-csv $base_file -Delimiter ";"
$tmpFile = "$dir\lineNumberOfMatches.txt"
$tmpFile2 = "$dir\newDates.txt"

foreach ($item in $import){
$source_base = $item.SOURCE
$pays_base = $item.PAYS
$symbo_base = $item.'SYMBO RZO'
$freq_base = $item.FREQUENCE
$periode_base = $item.PERIODE
$affectation_base = $item.AFFECTATION
$rang_base = $item.RANG
$indic_base = $item.INDICATIF
$ancienneSymbo_base = $item.'ANCIENNE SYMBO'
$modulation_base = $item.MODULATION
$datePerception_base = $item.'DATE PERCEPTION'
$dateMAJ_base = $item.'DATE MAJ'

$string = "$source_base;$pays_base;$symbo_base;$freq_base;$periode_base;$affectation_base;$rang_base;$indic_base;$ancienneSymbo_base;$modulation_base"
$match = Get-Content $final_file | Select-String -SimpleMatch "$string"

$new_date = $datePerception_base
echo $match.LineNumber >> $tmpFile #On met les lignes qui matchent et donc à remplacer dans le fichier de base pour changer la valeur plus tard
echo $new_date >> $tmpFile2

}


$i=0

 ##That's here that I need help
foreach ($line in Get-Content $tmpFile |sort -Unique){
    $lineNumber = $line -1 
    $lineToChange = Get-Content $final_file | Select -Index ($lineNumber)
    $old_date = echo $lineToChange | %{ $_.Split(';')[10]; }
    $date = Get-Content $tmpFile2 | Select -Index $i
    ## I have the good results but can't place it at the right line number or overwrite the line
    $lineToChange -replace "$old_date", "$date" 
    $i++
}


rm $tmpFile 
rm $tmpFile2

Это сводит меня с ума, потому что я знаю с shell и sed, проблема была бы уже решена... Спасибо за чтение и извините за длинный пост!

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

1 ответ

У меня наконец получилось. Я надеюсь, что это может помочь кому-то...

##That's here that I need help
foreach ($line in Get-Content $tmpFile |sort -Unique){
    $lineNumber = $line -1 
    $lineToChange = Get-Content $final_file | Select -Index ($lineNumber)
    $old_date = echo $lineToChange | %{ $_.Split(';')[10]; }
    $date = Get-Content $tmpFile2 | Select -Index $i
    ## I have the good results but can't place it at the right line number or overwrite the line
    $lineToChange -replace "$old_date", "$date" 
    $i++
}

Заменен на:

$i=0
foreach ($line in Get-Content $tmpFile |sort -Unique){
    $content = Get-Content $final_file
    $lineNumber = $line -1
    $lineToChange = Get-Content $final_file | Select -Index ($lineNumber)
    #echo $lineToChange
    $old_date = echo $lineToChange | %{ $_.Split(';')[10]; }
    $date = Get-Content $tmpFile2 | Select -Index $i
    $new_line = $lineToChange -replace "$old_date", "$date"
    echo $new_line
    for ($y = 0; $y -le ($content.Length -1); $y++){
        if ($y -eq $lineNumber){
        $content[$y] = $new_line
        Set-Content $final_file $content
        }
    }

    $i++
}
Другие вопросы по тегам