Заменить строку на другую с определенным номером строки в текстовом файле - 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++
}