Søg og erstat

Tip 31 Printbar Monobook Forrige Næste

oprettet 2001 · kompleksitet grundlæggende · version 6.0

Vim leverer :s (erstatning) kommando til søgning og erstatning; dette tip viser eksempler på, hvordan man erstatter. På nogle systemer har gvim Find and Replace i menuen Rediger (: help: promptrepl), men det er lettere at bruge kommandoen :s på grund af kommandolinjens historie og evnen til at indsætte tekst (for eksempel ordet under markøren) til søgning eller udskiftning af felter.

Grundlæggende søgning og erstat

Kommandoen :substitute søger efter et tekstmønster og erstatter det med en tekststreng. Der er mange muligheder, men det er det, du sandsynligvis vil have:

:s/foo/bar/gFind hver forekomst af “foo” (kun i den aktuelle linje), og erstat den med “bar “.:%s/foo/bar/gFind hver forekomst af “foo” (i alle linjer), og erstat den med “bar”.:%s/foo/bar/gcSkift hver “foo” til “bar”, men bed først om bekræftelse.:%s/\<foo\>/bar/gcSkift kun hele ord, der præcist matcher “foo” til “bar”; bede om bekræftelse.:%s/foo/bar/gciSkift hver “foo” (store og små bogstaver på grund afiflag) til “bar”; bede om bekræftelse.:%s/foo\c/bar/gcer den samme, fordi\cgør søgningen ufølsom. Dette kan ønskes efter brug af:set noignorecasetil at gøre søgninger store og små bogstaver (standard).:%s/foo/bar/gcISkift hver “foo” (store og små bogstaver på grund afIflag) til “bar”; bede om bekræftelse.:%s/foo\C/bar/gcer det samme, fordi\Cgør søgningen stor og følsom. Dette kan ønskes efter brug af:set ignorecasetil at gøre søgninger store og små bogstaver.

Flagget g betyder global – hver forekomst i linjen ændres snarere end blot den første. Dette tip antager standardindstillingen for indstillingen "gdefault" og "edcompatible", hvilket kræver, at g flag inkluderes i %s///g for at udføre en global erstatning. Brug af :set gdefault skaber forvirring, fordi så er %s/// global, mens %s///g ikke er (det vil sige , g vender sin betydning).

Når du bruger c -flagget, skal du for hver kamp bekræfte, hvad at gøre. Vim udsender noget som: replace with foobar (y/n/a/q/l/^E/^Y)? (hvor foobar er erstatningsdelen af :s/.../.../ kommandoen. Du kan skrive y hvilket betyder at erstatte denne kamp, n for at springe denne kamp over, a for at erstatte denne og alle resterende kampe ( “alle” resterende kampe), q for at afslutte kommandoen, l for at erstatte denne kamp og afslutte (tænk på “sidste”), ^E for at rulle skærmen op ved at holde Ctrl-tasten og trykke på E og ^Y for at rulle skærmen ned ved at holde Ctrl-tasten og trykke Y. De sidste to valg er dog kun tilgængelige, hvis din Vim er en normal, stor eller enorm indbygget eller insert_expand-funktionen blev aktiveret på kompileringstidspunktet (se efter +insert_expand i output af :version).

Også når du bruger c flag, springer Vim til t hans første match finder den fra toppen af bufferen og beder dig om bekræftelse for at udskifte den match. Vim anvender IncSearch fremhævningsgruppen til den matchede tekst for at give dig et visuelt signal om, hvilket match det fungerer på (indstillet til reverse som standard for alle tre termtyper fra Vim 7.3). Derudover, hvis der findes mere end et match, og du har aktiveret søgning med :set hlsearch, fremhæver Vim de resterende kampe med Search fremhævningsgruppen . Hvis du bruger søgemarkering, skal du sørge for, at disse to fremhævningsgrupper adskiller sig visuelt, ellers vil du ikke være i stand til nemt at fortælle, hvilket match Vim beder dig om at erstatte.

Detaljer

Søgeområde:

Bemærk: Fra og med Vim 7.3 erstatninger anvendt på et område defineret med mærker eller et visuelt valg (som bruger en speciel type mærker “< og “>) er som standard ikke afgrænset af kolonnepositionen. I stedet anvender Vim erstatningen på hele linjen, hvor hvert mærke vises, medmindre\%Vatom bruges i mønsteret som::"<,">s/\%Vfoo/bar/g.

Når du søger:

.,*,\,angiver en / samling. Tegnområder kan repræsenteres med en-; for eksempel kan et bogstav a, b, c eller tallet 1 matches med. Neger samlingen medmatcher ethvert tegn undtagen a, b, c eller 1.\{#\}bruges til gentagelse./foo.\{2\}matcher foo og de to følgende tegn.\er ikke påkrævet i den afsluttende}/foo.\{2}vil gøre det samme.\(foo\)gør en backreference til foo. Parentes uden undslip matches bogstaveligt. Her kræves\for at lukke\).

Når du erstatter:

\rer ny linje, er\nen nulbyte (0x00).\&er ampersand (& er den tekst, der matcher søgemønsteret).\0indsætter teksten matchet med hele mønsteret\1indsætter teksten i den første backreference.\2indsætter den anden backreference osv.

Du kan bruge andre afgrænsere med erstatning:

:s#http://www.example.com/index.html#http://example.com/#

Gem indtastning ved hjælp af \zs og \ze for at indstille starten og slutningen af et mønster. For eksempel i stedet for:

:s/Copyright 2007 All Rights Reserved/Copyright 2008 All Rights Reserved/

Brug:

:s/Copyright \zs2007\ze All Rights Reserved/2008/

Brug af det aktuelle ord eller registrerer

:%s//bar/gErstat hvert match i det sidste søgemønster med “bar”. For eksempel kan du først placere markøren på ordetfooog derefter trykke på*for at søge efter det ord. Ovenstående erstatning vil derefter ændre alle ord, der nøjagtigt matcher “foo” til “bar”.

:%s/foo/<c-r><c-w>/gErstat hver forekomst af “foo” med ordet under markøren.<c-r><c-w>betyder, at du trykker på Ctrl-R og derefter Ctrl-W. Ordet under markøren indsættes som om du skrev det.:%s/foo/<c-r><c-a>/gErstat hver forekomst af “foo” med WORD under markøren (afgrænset af det hvide mellemrum).<c-r><c-a>betyder, at du trykker på Ctrl-R og derefter Ctrl-A. WORD under markøren indsættes som om du skrev det.:%s/foo/<c-r>a/gErstat hver forekomst af “foo” med indholdet af registeret “a”.<c-r>abetyder, at du trykker på Ctrl-R og dereftera. Indholdet af registeret “a” indsættes som om du skrev det.:%s/foo/<c-r>0/gSamme som ovenfor ved hjælp af register 0, der indeholder teksten fra den seneste yank-kommando. Eksempler på yank (kopi) kommandoer eryi(som kopierer teksten inden for parenteser omkring markøren, ogy$som kopierer teksten fra markøren til slutningen af linjen. Efter en yank-kommando, der ikke specificerede et destinationsregister, kan den kopierede tekst indtastes ved at trykke på Ctrl-R og derefter0.:%s/foo/\=@a/gErstat hver forekomst af “foo” med indholdet af registeret “a”.\=@aer en henvisning til registrering af “a”. Indholdet af registeret “a” vises ikke i kommandoen. Dette er nyttigt, hvis registeret indeholder mange tekstlinjer.:%s//<c-r>//gUdskift hvert match i det sidste søgemønster med/-registret (det sidste søgemønster). Efter at have trykket på Ctrl-R og derefter/for at indsætte det sidste søgemønster (og inden du trykker på Enter for at udføre kommandoen), kan du redigere teksten for at foretage de nødvendige ændringer.:%s/<c-r>*/bar/gErstat alle forekomster af teksten i systemudklipsholderen (i*-registret) med “bar” (se næste eksempel, hvis multiline) . På nogle systemer er alt hvad der kræves for at placere denne tekst i*-registret ved at vælge tekst (i Vim eller en anden applikation).:%s/<c-r>a/bar/gErstat alle forekomster af teksten i registeret “a” med “bar”.<c-r>abetyder, at du trykker på Ctrl-R og dereftera. Indholdet af registeret “a” indsættes som om du skrev det. Eventuelle nye linjer i register “a” indsættes som^Mog findes ikke. Søgningen fungerer, hvis hver^Mmanuelt erstattes med “\ n” (to tegn: tilbageslag, “n”). Denne udskiftning kan udføres, mens du skriver kommandoen::%s/<c-r>=substitute(@a,"\n","\\n","g")<CR>/bar/g"\n"(dobbelt anførselstegn) repræsenterer den nye linjes nye tegn;"\\n"(enkelt anførselstegn) repræsenterer to tilbageslag efterfulgt af “n“.Funktionensubstitute()

evalueres af<c-r>=(Ctrl-R=) ekspressionsregister; den erstatter hver ny linje med et enkelt tilbageslag efterfulgt af “n“.<CR>angiver, at du trykker på Enter for at afslutte=-udtrykket.:%s/<c-r>0/bar/gSamme som ovenfor ved hjælp af register 0, der indeholder teksten fra den seneste yank-kommando.

Se Indsæt registre i søge- eller kolon-kommandoer i stedet for at bruge udklipsholderen.

Yderligere eksempler

:%s/foo/bar/Udskift den første forekomst på hver linje af “foo” med “bar”.:%s/.*\zsfoo/bar/På hver linje skal du erstatte den sidste forekomst af “foo” med “bar”.:%s/\<foo\>//gPå hver linje skal du slette alle forekomster af hele ordet “foo”.:%s/\<foo\>.*//På hver linje skal du slette hele ordet “foo” og al den følgende tekst (til slutningen af linjen).:%s/\<foo\>.\{5}//På hver linje skal du slette den første forekomst af hele ordet “foo” og de følgende fem tegn.:%s/\<foo\>\zs.*//På hver linje skal du slette al tekst efter hele ordet “foo” (til slutningen af linjen).:%s/.*\<foo\>//På hver linje skal du slette hele ordet “foo” og al foregående tekst (fra begyndelsen af linjen).:%s/.*\ze\<foo\>//På hver linje skal du slette al teksten forud for hele ordet “foo” (fra begyndelsen af linjen).:%s/.*\(\<foo\>\).*/\1/På hver linje skal du slette al teksten forud for og følge hele ordet “foo”.:%s/\<foo\(bar\)\@!/toto/gPå hver linje skal du erstatte hver forekomst af “foo” (som starter et ord og ikke efterfølges af “bar”) med “toto”.:s/^\(\w\)/\u\1/Hvis det første tegn i begyndelsen af den aktuelle linje kun er med små bogstaver, skal du skifte det til store bogstaver ved hjælp af\u(se skift mellem store og små bogstaver for tegn ).:%s/\(.*\n\)\{5\}/&\r/Indsæt en tom linje hver 5. linje. Mønsteret søger efter\(.*\n\)(enhver linje inklusive linjeafslutning) gentaget fem gange (\{5\}). Erstatningen er&(den tekst, der blev fundet), efterfulgt af\r(ny linje).:%s/\<foo\(\a*\)\>/\=len(add(list, submatch(1)))?submatch(0):submatch(0)/gFå en liste over søgeresultater. (listen skal eksistere) Indstillermodifiedflag på grund af udskiftningen, men indholdet er uændret. Bemærk: Med et nyligt nok Vim (version 7.3.627 eller højere) kan du forenkle dette til::%s/\<foo\(\a*\)\>/\=add(list, submatch(1))/gnDette har den fordel, at bufferen ikke bliver markeret ændret og ingen ekstra fortrydelsestilstand oprettes. Udtrykket i erstatningsdelen udføres i sandkassen og må ikke ændre bufferen.

Særlige tilfælde

For at erstatte mønstre med tilsvarende store og små bogstaver, Michael Geddes ” s Keepcase-plugin kan bruges, fx:

:%SubstituteCase/\cHello/goodBye/gErstat “Hello hej helLo HELLO” med “Farvel farvel goodBye GOODBYE”

Til ændring af forskydninger i en patch-fil (linienummer på en blok), kan dette lille uddrag bruges:

s/^@@ -\(\d\+\),\(\d\+\) +\(\d\+\),\(\d\+\) @@$/\="@@ -".eval(submatch(1)+offsetdiff).",".submatch(2)." +".eval(submatch(3)+offsetdiff).",".submatch(4)." @@"/g

Nyttigt, når vi vil fjerne nogle blokke fra en patch, uden at patch skal klage over forskydningsforskelle.

Bemærk Bør forsøge at gøre udtrykket mere kompakt, men ved ikke hvordan uden at have mulighed for at ændre uønskede linjer.

Se også: brug af erstatning

  • 63 Anvendelse af erstatninger på en visuel blok
  • 81 Erstat let tegn og linjer
  • 159 Tastetryk Gem udskiftning og søgning
  • 406 Alternative afgrænsere til erstatningen kommando
  • 438 Søg og erstat i et visuelt valg
  • 464 Søg og erstat ordet under markøren
  • 479 Udskift uden at skrive
  • 573 Gentagelse af en erstatning fra den aktuelle markørposition
  • 605 Erstat et ord med den ryste tekst
  • 654 Specialtegn i erstatningskommandoen
  • 755 Brug af et udtryk i erstatningskommando
  • 808 Erstat en visuel tekstblok med en anden sådan blok
  • 915 Brug af g i stedet for erstatning
  • 971 Erstat med stigende tal
  • 1114 Trinforhøjelse og udskift
  • 1501 Erstat sidste søgning

Se også: erstat i buffere / filer

  • 382 Søg og udskift i flere buffere
  • : hjælp: erstat
  • : hjælp cmdline-r anges
  • : hjælpemønster
  • : hjælp “gdefault”
  • : hjælpregistre

AT GØRE
The stort “se også” afsnit kan være nyttigt for læsere. Vi er nødt til at flette nogle af de relaterede tip (men gør ikke resultatet for komplekst). Jeg inkluderede tipnumrene for at hjælpe redaktører med at holde styr på.

Ønsker et kort afsnit, der nævner, at enkle erstatninger ofte er bedst håndteres ved at søge og derefter manuelt ændre (og trykke på . for at gentage den sidste ændring.) Derudover kan du beslutte, hvordan du vil ændre hver forekomst.Se Kopiér eller skift søgehit for en teknik, hvor du kan trykke på n for at finde den næste forekomst, og skriv derefter cs for at ændre søgehit til hvad som helst.

Har der for nylig været en ændring med, hvordan% s fungerer? På en eller anden måde kan jeg bruge både < cr > og \ = @ som erstatninger, men jeg kan ikke bruge dem som søgninger og erstatninger.

Hvis du beskriver nøjagtigt, hvad du laver, og hvad der sker, kan jeg muligvis hjælpe, selvom jeg stiller spørgsmål. JohnBeckett (diskussion) 02:15, 1. juni 2019 (UTC)

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *