Præprocessorkommandoer

KDiff3 understøtter to præprocessortilvalg.

Præprocessorkommando:

Når en fil læses, sendes den via denne eksterne kommando. Uddata fra denne kommando vises i stedet for den oprindelige fil. Du kan skrive din egen præprocessor som opfylder dine specielle behov. Brug dette til at fjerne forstyrrende dele af filen, eller for automatisk at korrigere indrykning, osv.

Præprocessorkommando for linjematchning:

Når en fil læses, sendes den via denne eksterne kommando. Hvis en præprocessorkommando (se ovenfor) også angives er udskriften fra præprocessoren input til kommandoen for linjematchning. Udskriften bruges kun under linjematchningsfasen af analysen. Du kan skrive din egen præprocessor som opfylder dine specielle behov. Hvert inddatalinje skal have en tilsvarende uddatalinje.

Idéen er at tillade brugeren større fleksibilitet mens diff-resultatet indstilles. Men dette kræver et eksternt program, og mange brugere ønsker ikke selv at skrive et sådant. Heldigvis er det meget ofte sådan at sed or perl vil kunne klare det.

Eksempel: Enkelt testtilfælde. Betragt filen a.txt (6 linjer):

aa
ba
ca
da
eafa

Og filen b.txt (3 linjer):

cg
dg
eg

Uden præprocessor ville følgende linjer blive placeret ved siden af hinanden:

aa - cg
ba - dg
ca - eg
da
ea
fa

Dette er formodentlig ikke ønskværdigt, eftersom det første bogstav indeholder den virkelig interessante information. For at hjælpe matchningsalgoritmen med at ignorere det andet bogstav kan vi bruge en linjematchningskommando i præprocessoren som erstatter g med a.

sed 's/g/a/'

Med denne kommando ville resultatet af sammenligningen blive:

aa
ba
ca - cg
da - dg
ea - eg
fa

Internt ser matchningsalgoritmen filerne efter at have kørt præprocessoren med linjematchning, men på skærmen er filen uforandret. (Den normale præprocessor ville også ændre data på skærmen.)

Basal sed

Dette afsnit introducerer blot nogle meget grundlæggende funktioner i sed. For mere information se info:/sed eller http://www.gnu.org/software/sed/manual/html_mono/sed.html. En forkompileret version for Windows® eksisterer på http://unxutils.sourceforge.net. Bemærk at følgende eksempel antager at sed eksisterer i en mappe i miljøvariablen PATH. Hvis dette ikke er tilfældet, skal du angive fuldstændig absolut søgesti til kommandoen. Bemærk også at følgende eksempel bruger enkle citationstegn ('), hvilket ikke virker i Windows®. I Windows® skal du i stedet bruge dobbelte citationstegn (").

I denne sammenhæng bruges kun erstatningskommandoen i sed:

sed 's/Regulært udtryk/Erstatning/Flag'

Inden du bruger en ny kommando inde i KDiff3 bør du først teste den i en terminal. Her er kommandoen echo nyttig. For eksempel:

echo abrakadabra | sed 's/a/o/'
obrakadabra

Dette eksempel viser en meget enkel sed-kommando som erstatter første forekomst af “a” med “o”. Hvis du vil erstatte alle forekomster, behøver du flaget g:

echo abrakadabra | sed 's/a/o/g'
obrokodobro

Symbolet “|” er rørkommandoen som overfører uddata fra foregående kommando til inddata i efterfølgende kommando. Hvis du vil teste med en længere fil kan du bruge cat på Unix-lignende systemer eller typeWindows®-lignende systemer. sed udfører erstatningen på hver linje.

cat filnavn |sed flag

Eksempel på brug af sed i KDiff3

Ignorering af andre typer kommentarer

For øjeblikket forstår KDiff3 kun C/C++ syntaks. Ved at bruge den linjematchende præprocessorkommando kan du også ignorere andre typer af kommentarer, ved at konvertere dem til C/C++ kommentarer.

For at ignorere kommentarer som begynder med #, vil du konvertere dem til //. Bemærk at du skal aktivere tilvalget Ignorér C/C++ kommentarer for at få nogen effekt. En passende linjematchende præprocessorkommando ville være:

sed 's/#/\/\//'

Eftersom tegnet / har en særlig betydning i sed, er det nødvendigt at tilføje tegnet \ inden hvert / i erstatningsstrengen. Sommetider behøves \ for at tilføje eller fjerne en særlig betydning for visse tegn. De enkle citationstegn (') inden og efter erstatningskommandoen er nu vigtige, eftersom skallen ellers ville forsøge at tolke visse specialtegn såsom #, $ eller \ inden de sendes til sed. Bemærk at i Windows® behøver du dobbelte citationstegn (") her. Windows® erstatter andre tegn såsom %, så du kan behøve at eksperimentere noget.

Ikke versalfølsom Diff

Brug følgende linjematchende præprocessorkommando for at konvertere al inddata til store bogstaver:

sed 's/\(.*\)/\U\1/'

Her er “.*” et regulært udtryk som matcher alle strenge, og i denne sammenhæng matcher alle tegn på linjen. Tegnet \1 i erstatningsstrengen svarer til den matchede tekst mellem det første par \( og \). \U konverterer den indsatte tekst til store bogstaver.

Ignorering af nøgleord for versionskontrol

CVS og andre versionskontrolsystemer bruger flere nøgleord for at indsætte automatisk oprettede strenge (info:/cvs/Keyword substitution). Alle følger mønstret $NØGLEORD oprettet tekst$. Nu behøver vi en linjematchende præprocessorkommando som kun fjerner den oprettede tekst:

sed 's/\$\(Revision\|Author\|Log\|Header\|Date\).*\$/\$\1\$/'

Tegnet \| skiller de mulige nøgleord ad. Du kan ville ændre listen ifølge dine behov. Tegnet \ inden $ er nødvendigt eftersom tegnet $ ellers matcher linjeslutningen.

Mens du eksperimenterer med sed kommer du måske til at forstå og endog at kunne lide disse regulære udtryk. De er nyttige fordi der er mange andre programmer der også understøtter lignende ting.

Ignorér cifre

At ignorere cifre er i virkeligheden et indbygget tilvalg, men som et andet eksempel, vises hvordan det ville se ud som en linjematchende præprocessorkommando.

sed 's/[0123456789.-]//g'

Alle tegn indeni [ og ] matcher og erstattes med ingenting.

Ignorering af visse søjler

Sommetider er teksten meget strengt formateret, og indeholder søjler som du altid vil ignorere, mens der er andre søjler du vil bevare for analyse. I følgende eksempel ignoreres de fem første søjler (tegn), de følgende ti søjler bevares, derefter ignoreres igen fem søjler og resten af linjen bevares.

sed 's/.....\(..........\).....\(.*\)/\1\2/'

Hvert punkt . matcher et enkelt tegn. \1 og \2 i erstatningsstrengen henviser til matchende tekst indenfor det første og andet par af \( og \) som angiver teksten som skal bevares.

Kombination af flere substitutioner

Sommetider vil du anvende flere erstatninger samtidigt. Så kan du bruge semikolon ; til at skille dem fra hinanden.

echo abrakadabra | sed 's/a/o/g;s/\(.*\)/\U\1/'
OBROKODOBRO

Brug af perl i stedet for sed

I stedet for sed vil du måske bruge noget andet, såsom perl.

perl -p -e 's/Regulært udtryk/Erstatning/Flag'

Men visse detaljer adskiller sig i perl. Bemærk at hvor sed behøvede \( og \) kræver perldet enklere ( og ) uden indledende \.

sed 's/\(.*\)/\U\1/'
perl -p -e 's/(.*)/\U\1/'

Rækkefølge for præprocessor-udførsel

Data sendes gennem alle interne og eksterne præprocessorer i følgende rækkefølge:

  • Normal præprocessor,

  • Præprocessor for linjematchning,

  • Ignorér versaler (konvertér til store bogstaver),

  • Detektion af C/C++ kommentarer,

  • Ignorér cifre,

  • Ignorér blanke tegn

Data efter den normale præprocessor vil blive bevaret til visning og indfletning. De andre operationer ændrer kun de data som den linjematchende diff-algoritme ser.

I de sjældne tilfælde hvor du bruger en normal præprocessor, bemærk at den linjematchende præprocessor ser uddata fra den normale præprocessor som inddata.

Advarsel

Forbehandlingskommandoer er ofte meget nyttige, men som med alle tilvalg som ændrer teksten eller skjuler visse forskelle automatisk, kan du ved en fejl springe over visse forskelle og i værste fald ødelægge vigtige data.

Af denne grund, hvis en normal præprocessorkommando bruges under en sammenfletning, fortæller KDiff3 dig om det og spørger om det skal deaktiveres eller ej. Men du får ingen advarsel hvis en linjematchende præprocessorkommando er aktiv. Sammenfletningen sker ikke førend alle konflikter er løste. Hvis du deaktiverede Vis blanke tegn bliver også forskellene som blev fjernet med den linjematchende præprocessorkommando usynlige. Hvis knappen Gem forbliver inaktiv under en sammenfletning (på grund af tilbageværende konflikter), så sørg for at aktivere Vis blanke tegn. Hvis du ikke vil sammenflette disse mindre vigtige forskelle manuelt kan du vælge Vælg [A|B|C] for uløste konflikter med blanke tegn i menuen Sammenflet.