操作文本文件 - 更改多行

Manipulate text file - change multiple lines

今天早上我一直在看我认为会是一个非常简单的任务......结果证明它不是,至少对我来说不是。

我想要做的是让 powershell 读取 ini-file,并仅更改特定 headers 下的多个值。

[Datoformat]
Separator=.
[Database]
Path=servername:d:\mycompany\nextsys_db\next.fdb
DokumentDbPath=
FireBird25=Nei

[Pictures]
Path=T:\nextsys_bilde
DbExtractFolder=

[Brukerinnstillinger]
Prioriter=Ja
�pneJournalAuto=Nei
TillatBrukerBytte=Ja
EnkelJournal=Nei
AvtBokRadHoyde=
AvtBokMndKolonneBredde=
Resepsjonsmaskin=Nei
Tilgangsoversikt=Nei
AvtaleHentPasientAutomatisk=Ja
VisFargeForAnsvarlig=Nei
[Eksport]
Automatisk=Nei
[Import]
Automatisk=Nei
[Skjerm]
HuskSkjermPosisjon=Ja
ProgramSkjermPosX=-8
ProgramSkjermPosY=-8
ProgramSkjermBredde=1936
ProgramSkjermHoyde=1056
MaksimertSkjermPosisjon=Ja
EgenDefSkjermSizeX=1919
EgenDefSkjermSizeY=1080
UtvidetAvtalebok=Ja
UtvidetJournal=Ja
UtvidetRecall=Ja
UtvidetOmsetning=Ja
UtvidetUtestaaende=Ja
UtvidetRegnskap=Ja
UtvidetFakturaOversikt=Ja
UtvidetGenerelleModuler=Ja
UtvidetAlleModuler=Ja
1280800=Nei
1440900=Nei
16801050=Nei
19201080=Nei
Egendefinert=Ja
AutomaticSize=Nei
[Spesialinnstillinger]
EnForekomst=Nei
TestModusInfo=Nei
AktiverRegningskortJournalSjekk=Nei
IkkeSpmOmHelseskjema=Nei
IkkeSpmOmBrukerBytteAvtale=Nei
IkkeSpmOmBrukerBytteAnsvarlig=Nei
[Vedlegg]
Path=
[Avtalebok]
Utseende=
Bakgrunn=
[Journal]
JournalTextSize=8
JournalTextFont=
JournalTextStyle=
FetSkrift=Nei
[Rontgen]
AlternativAapning=Nei
[Utseende]
IkkeVisDagensPasienter=Nei
[MediLink]
BenyttMediLink=Nei
AutomatiskInnlesing=Nei
MediLinkInnlesingIntervall=
[AutomatiskOppdatering]
VedOppstart=Nei
Alltid=Nei
FraLokaltNettverk=Nei
NettverkPath=
UtenBekreftelse=Nei
[BankTerminal]
PosPay=Nei
BetTermAlwaysOn=Ja
BBSFlerBrukerTerminal=Nei
ThisMerchantHighest=Nei
MerchantId=
TerminalId=
BrukerBoPosDrivere=Nei
BrukerBaxiDrivere=Ja
BaxiAktiverXReport=Ja
BaxiAktiverZReport=Nei
BaxiAktiverReversal=Nei
[EasyPanel]
Benytt=Nei
Notat=Nei
Diagnose=Nei
Epikriser=Nei
Sykemelding=Nei
Resept=Nei
Henvisning=Nei
Helseskjema=Nei
Endo=Nei
Perio=Nei
Bilder=Nei
Tekn.skjema=Nei
Skjema=Nei
Dokumentmodul=Nei
[Oppstartsbilde]
VisesVedOppstart=Nei
[Printer]
LokaltOppsett=Ja
TryktA5Resept=Nei
TryktA5ReseptDesign2=Nei
TimeKortKvittSkriver=Nei
VisMinimalBaxInfo=Nei
ReseptKvittSkriver=Nei
JusteringVenstreMargX=
JusteringToppMargY=
Faktura=HP LaserJet Pro MFP M125-M126 PCLmS
Recallkort=HP LaserJet Pro MFP M125-M126 PCLmS
Timekort=HP LaserJet Pro MFP M125-M126 PCLmS
Kvittering=HP LaserJet Pro MFP M125-M126 PCLmS
Resept=HP LaserJet Pro MFP M125-M126 PCLmS
Standard=HP LaserJet Pro MFP M125-M126 PCLmS
Tekniker=HP LaserJet Pro MFP M125-M126 PCLmS
FakturaStorrelse=A4
RecallKortStorrelse=A4
TimekortStorrelse=A4
KvitteringStorrelse=A4
ReseptStorrelse=A4
TeknikerStorrelse=A4
StandardStorrelse=A4
FakturaOppsettKode=
RecallkortOppsettKode=
TimekortOppsettKode=
KvitteringOppsettKode=
ReseptOppsettKode=
TeknikerOppsettKode=
StandardOppsettKode=
FakturaPapirretning=St�ende
RecallKortPapirretning=St�ende
TimekortPapirretning=St�ende
KvitteringPapirretning=St�ende
ReseptPapirretning=St�ende
TeknikerPapirretning=St�ende
StandardPapirretning=St�ende
FakturaPreview=Ja
RecallKortPreview=Ja
TimekortPreview=Ja
KvitteringPreview=Ja
ReseptPreview=Ja
TeknikerPreview=Ja
StandardPreview=Ja
[Paaminnelse]
Automatisk=Nei
AutomatiskService=Nei
Tidspunkt=
Dagens=Nei
KunMerketOnsker=Nei
AutomatiskEpost=Nei
AntallDagerFrem=Nei
AntallDagerFremAntall=2
ErstattTekst=Nei
PaaminnelseTekst=Hei [fornavn], minner om time reservert til deg: [dato] kl. [tid]. Timer  som ikke passer m� avbestilles senest 24 timer i forveien.  Mvh.  [tittel] [brukernavn]  
[SMS]
Testmodus=Nei
VisAdvarslerVedIkkeSendtSMS=Nei
[Innlogging]
TillatInnloggingMedEldreProgramversjonEnnDatabase=Nei

我想将值“Automatisk=Nei”更改为“Automatisk=Ja”,“Tidspunkt=”更改为“Tidspunkt=10:00”,“AntallDagerFrem=Nei”更改为“AntallDagerFrem=Ja”... Tidspunkt 和 AntallDagerFrem 的值应该不难,因为它们只在文件中出现一次,但“Automatisk=Nei”出现了 4 次,我只想更改下面的 [Paaminnelse]

$content = @(if ((Get-Content $inifile) -join "`n" -match '\[Paaminnelse\]([\s\S]*)\[SMS\]') { $Matches[1] }) 

$newcontent = $test -replace  'Automatisk=Nei','Automatisk=Ja' -replace 'Tidspunkt=','Tidspunkt=10:00' -replace 'AntallDagerFrem=Nei','AntallDagerFrem=Ja'

这从 ini-file 中找到了正确的行并更改了我想要更改的值,但是使用 Set-Content $inifile -Value $newcontent 当然会从文件中删除所有其他不是我想要的内容: )

老实说,比 PowerShell 更习惯使用 cat、grep、awk 和 sed,所以任何指点都会有所帮助。

作为 Theo notes, consider using a dedicated INI file parser, such as the one provided by the third-party PsIni module - see 如何安装和使用它。

  • 更新 现在展示了如何使用它来解决您的特定问题.

如果安装模块不是一个选项,我建议使用 -switch 语句,它具有类似 awk 的功能:

# Array of sample lines, as would be returned by:
#   Get-Content $inifile
$iniFileLines = @'
[Datoformat]
Separator=.

[Eksport]
Automatisk=Nei

[Paaminnelse]
Automatisk=Nei
AutomatiskService=Nei
Tidspunkt=

[Printer]
AutomatiskEpost=Nei
AntallDagerFrem=Nei
AntallDagerFremAntall=2
'@ -split '\r?\n'

$inPaaminnelseSect = $false

# Note: To operate directly on your file, replace 
#       ($iniFileLines) with -File $iniFile
switch -Regex ($iniFileLines) {
  '^(Tidspunkt)=$' { '{0}=10:00' -f $Matches[1]; continue }
  '^(AntallDagerFrem)=Nei' { '{0}=Ja' -f $Matches[1]; continue }
  '^(Automatisk)=Nei' { 
    if ($inPaaminnelseSect) { '{0}=Ja' -f $Matches[1] } else { $_ }; continue 
  }
  '^\[(.+)\]' { $inPaaminnelseSect = $Matches[1] -eq 'Paaminnelse'; $_ }
  default { $_ } # pass through
}

注:

  • 以上假设:

    • 您的文件的格式与您问题中显示的格式完全一致。但是,就可选空格而言,很容易使解析更加灵活。

    • 您只想替换具有特定当前值的条目(或 none);这也可以很容易地更改以替换值,而不管当前值如何。

  • 匹配是不区分大小写的不敏感,因为PowerShell通常是默认的;添加 -CaseSensitive 开关使其成为 case-sensitive.

输出:

[Datoformat]
Separator=.

[Eksport]
Automatisk=Nei

[Paaminnelse]
Automatisk=Ja
AutomatiskService=Nei
Tidspunkt=10:00

[Printer]
AutomatiskEpost=Nei
AntallDagerFrem=Ja
AntallDagerFremAntall=2

Theo and mklement0 都指向了 PsIni-module 这正是我想做的 - 所以考虑回答的问题。

Set-IniContent $inifile -Sections 'Paaminnelse' -NameValuePairs @{
  Automatisk='Ja'; Tidspunkt='10:00'; AntallDagerFrem='Ja'
} | Out-IniFile $inifile -Force