diff(1p): Skillnad mellan sidversioner
Admin (diskussion | bidrag) |
Admin (diskussion | bidrag) (→Sidfot) |
||
| Rad 596: | Rad 596: | ||
* https://www.kernel.org/doc/man-pages/reporting_bugs.html | * https://www.kernel.org/doc/man-pages/reporting_bugs.html | ||
== Sidor som hänvisar till denna sida == | == Sidor som hänvisar till denna sida == | ||
Versionen från 7 maj 2026 kl. 05.36
diff(1p) – Linux manualsida
Prolog
Den här manualsidan är en del av POSIX Programmer's Manual.
Linux-implementationen av detta gränssnitt kan skilja sig åt. Se motsvarande Linux-manualsida för detaljer om Linux-beteende. Gränssnittet kanske inte heller är implementerat på Linux.
Namn
diff – jämför två filer.
Synopsis
diff [-c|-e|-f|-u|-C n|-U n] [-br] fil1 fil2
Beskrivning
Verktyget diff ska jämföra innehållet i fil1 och fil2 och skriva en lista till standardutmatning över de ändringar som behövs för att omvandla fil1 till fil2.
Listan bör vara minimal.
Ingen utmatning ska skapas om filerna är identiska.
Flaggor
Verktyget diff ska följa POSIX.1-2017, Base Definitions, avsnitt 12.2, Utility Syntax Guidelines.
Följande flaggor ska stödjas:
- -b
- Gör att valfri mängd blanktecken i slutet av en rad behandlas som ett enda radbrytningstecken. Det vill säga blanktecken före radbrytningen ignoreras.
- Andra strängar av blanktecken, exklusive radbrytningstecken, ska jämföras som lika.
- -c
- Skapa utdata i ett format som ger tre rader kopierad kontext.
- -C n
- Skapa utdata i ett format som ger n rader kopierad kontext.
- n ska tolkas som ett positivt decimalt heltal.
- -e
- Skapa utdata i ett format som lämpar sig som indata till verktyget ed. Detta kan sedan användas för att omvandla fil1 till fil2.
- -f
- Skapa utdata i ett alternativt format, liknande formatet för -e, men inte avsett att vara lämpligt som indata till verktyget ed, och i motsatt ordning.
- -r
- Tillämpa diff rekursivt på filer och kataloger med samma namn när både fil1 och fil2 är kataloger.
- Verktyget diff ska upptäcka oändliga loopar, det vill säga när det går in i en tidigare besökt katalog som är en förfader till den senast påträffade filen.
- När en oändlig loop upptäcks ska diff skriva ett diagnostiskt meddelande till standardfel och antingen återställa sin position i hierarkin eller avsluta.
- -u
- Skapa utdata i ett format som ger tre rader enhetlig kontext.
- -U n
- Skapa utdata i ett format som ger n rader enhetlig kontext.
- n ska tolkas som ett icke-negativt decimalt heltal.
Operander
Följande operander ska stödjas:
- fil1, fil2
- Sökvägar till filer som ska jämföras.
- Om antingen fil1 eller fil2 är -, ska standardinmatning användas i dess ställe.
Om både fil1 och fil2 är kataloger ska diff inte jämföra blockspecialfiler, teckenspecialfiler eller FIFO-specialfiler med några filer, och ska inte jämföra vanliga filer med kataloger.
Ytterligare detaljer anges i avsnittet Diff-katalogjämförelseformat.
Beteendet hos diff för andra filtyper är implementationsdefinierat när de hittas i kataloger.
Om endast en av fil1 och fil2 är en katalog, ska diff tillämpas på den fil som inte är en katalog och den fil som finns i katalogen och vars filnamn är samma som den sista komponenten i sökvägen för filen som inte är en katalog.
Standardinmatning
Standardinmatning ska endast användas om någon av operanderna fil1 eller fil2 hänvisar till standardinmatning.
Se avsnittet Indatafiler.
Indatafiler
Indatafilerna kan vara av vilken typ som helst.
Miljövariabler
Följande miljövariabler ska påverka körningen av diff:
- LANG
- Anger ett standardvärde för internationaliseringsvariabler som är osatta eller tomma.
- Se POSIX.1-2017, Base Definitions, avsnitt 8.2, Internationalization Variables, för företrädesordningen för internationaliseringsvariabler som används för att bestämma värden för lokalkategorier.
- LC_ALL
- Om den är satt till en icke-tom sträng åsidosätter den värdena för alla andra internationaliseringsvariabler.
- LC_CTYPE
- Bestämmer lokalen för tolkning av byteföljder i textdata som tecken, till exempel enkelbyte- jämfört med multibytetecken i argument och indatafiler.
- LC_MESSAGES
- Bestämmer lokalen som ska användas för att påverka formatet och innehållet i diagnostiska meddelanden som skrivs till standardfel och informativa meddelanden som skrivs till standardutmatning.
- LC_TIME
- Bestämmer lokalen för formatet på filtidsstämplar som skrivs med flaggorna -C och -c.
- NLSPATH
- Bestämmer platsen för meddelandekataloger vid bearbetning av LC_MESSAGES.
- TZ
- Bestämmer tidszonen som används för att beräkna filtidsstämplar som skrivs i ett kontextformat.
- Om TZ är osatt eller tom ska en ospecificerad standardtidszon användas.
Asynkrona händelser
Standardbeteende.
Standardutmatning
Diff-katalogjämförelseformat
Om både fil1 och fil2 är kataloger ska följande utdataformat användas.
I POSIX-lokalen ska varje fil som endast finns i en katalog rapporteras med följande format:
"Only in %s: %s\n", <katalogsökväg>, <filnamn>
I POSIX-lokalen kan underkataloger som är gemensamma för de två katalogerna rapporteras med följande format:
"Common subdirectories: %s and %s\n", <katalog1-sökväg>, <katalog2-sökväg>
För varje fil som är gemensam för de två katalogerna, om de två filerna inte ska jämföras: om de två filerna har samma enhets-ID och filserienummer, eller båda är blockspecialfiler som hänvisar till samma enhet, eller båda är teckenspecialfiler som hänvisar till samma enhet, är utdataformatet ospecificerat i POSIX-lokalen.
I annat fall ska ett ospecificerat format användas i POSIX-lokalen, men det ska innehålla sökvägarna till de två filerna.
För varje fil som är gemensam för de två katalogerna, om filerna jämförs och är identiska, ska ingen utmatning skrivas.
Om de två filerna skiljer sig åt skrivs följande format:
"diff %s %s %s\n", <diff-flaggor>, <filnamn1>, <filnamn2>
där diff-flaggor är de flaggor som angavs på kommandoraden.
Alla katalogsökvägar som anges i detta avsnitt ska vara relativa till de ursprungliga kommandoradsargumenten.
Alla andra filnamn som anges i detta avsnitt ska vara filnamn, det vill säga sökvägskomponenter.
Diff-binärutdataformat
I POSIX-lokalen, om en eller båda filerna som jämförs inte är textfiler, är det implementationsdefinierat om diff använder binärfilutdataformatet eller de andra formaten som anges nedan.
Binärfilutdataformatet ska innehålla sökvägarna till de två filer som jämförs och strängen "differ".
Om båda filerna som jämförs är textfiler ska, beroende på angivna flaggor, ett av följande format användas för att skriva skillnaderna.
Diff-standardutdataformat
Standardutdata från diff, utan flaggorna -e, -f, -c, -C, -u eller -U, ska innehålla rader av följande former:
"%da%d\n", <num1>, <num2> "%da%d,%d\n", <num1>, <num2>, <num3> "%dd%d\n", <num1>, <num2> "%d,%dd%d\n", <num1>, <num2>, <num3> "%dc%d\n", <num1>, <num2> "%d,%dc%d\n", <num1>, <num2>, <num3> "%dc%d,%d\n", <num1>, <num2>, <num3> "%d,%dc%d,%d\n", <num1>, <num2>, <num3>, <num4>
Dessa rader liknar ed-underkommandon för att omvandla fil1 till fil2.
Radnumren före åtgärdsbokstäverna ska avse fil1. De efter åtgärdsbokstäverna ska avse fil2.
Genom att byta ut a mot d och läsa raden i omvänd ordning kan man också avgöra hur fil2 ska omvandlas till fil1.
Som i ed förkortas identiska par, där num1 = num2, till ett enda nummer.
Efter varje sådan rad ska diff skriva alla berörda rader i den första filen till standardutmatning med formatet:
"< %s", <rad>
och alla berörda rader i den andra filen med formatet:
"> %s", <rad>
Om det finns berörda rader i både fil1 och fil2, som med underkommandot c, separeras ändringarna med en rad som består av tre bindestreck:
"---\n"
Diff -e-utdataformat
Med flaggan -e ska ett skript skapas som, när det ges som indata till ed tillsammans med ett tillagt w-kommando, omvandlar fil1 till fil2.
Endast kommandona a för append, c för change, d för delete, i för insert och s för substitute i ed ska användas i detta skript.
Textrader, förutom de som endast består av ett ensamt punkttecken, ska skrivas ut som de förekommer i filen.
Diff -f-utdataformat
Med flaggan -f ska ett alternativt skriptformat skapas.
Det liknar formatet som skapas med -e, med följande skillnader:
- Det uttrycks i omvänd sekvens. Utdata från -e ordnar ändringar från filens slut till dess början. Utdata från -f ordnar ändringar från början till slut.
- Kommandoformen rader kommando-bokstav som används av -e är omvänd. Till exempel skulle 10c med -e bli c10 med -f.
- Formen som används för intervall av radnummer är separerad med mellanslag i stället för kommatecken.
Diff -c- eller -C-utdataformat
Med flaggan -c eller -C ska utdataformatet bestå av berörda rader tillsammans med omgivande kontextrader.
De berörda raderna ska visa vilka rader som behöver tas bort eller ändras i fil1, samt vilka som lagts till från fil2.
Med flaggan -c ska tre kontextrader, om tillgängliga, skrivas före och efter de berörda raderna.
Med flaggan -C kan användaren ange hur många kontextrader som ska skrivas.
Det exakta formatet följer nedan.
Namnet och den senaste ändringstiden för varje fil ska skrivas i följande format:
"*** %s %s\n", fil1, <fil1-tidsstämpel> "--- %s %s\n", fil2, <fil2-tidsstämpel>
Varje fil-fält ska vara sökvägen till motsvarande fil som jämförs.
Sökvägen som skrivs för standardinmatning är ospecificerad.
I POSIX-lokalen ska varje tidsstämpel-fält motsvara utdata från följande kommando:
date "+%a %b %e %T %Y"
utan avslutande radbrytning, kört vid den senaste ändringstiden för motsvarande fil, eller aktuell tid om filen är standardinmatning.
Därefter ska följande utdataformat tillämpas för varje uppsättning ändringar.
Först ska en rad skrivas med följande format:
"***************\n"
Därefter ska radintervallet i fil1 skrivas med följande format om intervallet innehåller två eller fler rader:
"*** %d,%d ****\n", <börjanradnummer>, <slutradnummer>
och annars med följande format:
"*** %d ****\n", <slutradnummer>
Slutradnumret för ett tomt intervall ska vara numret på föregående rad, eller 0 om intervallet är i början av filen.
Därefter ska de berörda raderna tillsammans med kontextrader, det vill säga opåverkade rader, skrivas.
Opåverkade rader ska skrivas i följande format:
" %s", <opåverkad_rad>
Borttagna rader ska skrivas som:
"- %s", <borttagen_rad>
Ändrade rader ska skrivas som:
"! %s", <ändrad_rad>
Därefter ska radintervallet i fil2 skrivas med följande format om intervallet innehåller två eller fler rader:
"--- %d,%d ----\n", <börjanradnummer>, <slutradnummer>
och annars med följande format:
"--- %d ----\n", <slutradnummer>
Sedan ska kontextrader och ändrade rader skrivas enligt tidigare format.
Rader som lagts till från fil2 ska skrivas i följande format:
"+ %s", <tillagd_rad>
Diff -u- eller -U-utdataformat
Flaggorna -u och -U beter sig som flaggorna -c och -C, förutom att kontextraderna inte upprepas. I stället visas kontext, borttagna rader och tillagda rader tillsammans, inflätade.
Det exakta formatet följer nedan.
Namnet och den senaste ändringstiden för varje fil ska skrivas i följande format:
"--- %s\t%s%s %s\n", fil1, <fil1-tidsstämpel>, <fil1-fraktion>, <fil1-zon> "+++ %s\t%s%s %s\n", fil2, <fil2-tidsstämpel>, <fil2-fraktion>, <fil2-zon>
Varje fil-fält ska vara sökvägen till motsvarande fil som jämförs, eller det enskilda tecknet - om standardinmatning jämförs.
Om sökvägen innehåller en tabb eller en radbrytning, eller om den inte helt består av tecken från den portabla teckenuppsättningen, är beteendet implementationsdefinierat.
Varje tidsstämpel-fält ska motsvara utdata från följande kommando:
date '+%Y-%m-%d %H:%M:%S'
utan avslutande radbrytning, kört vid den senaste ändringstiden för motsvarande fil, eller aktuell tid om filen är standardinmatning.
Varje fraktion-fält ska antingen vara tomt eller en decimalpunkt följd av minst en decimalsiffra, som anger fraktionssekunddelen, om någon, av filtidsstämpeln.
Antalet fraktionssiffror ska vara minst det antal som behövs för att representera filens tidsstämpel utan informationsförlust.
Varje zon-fält ska ha formen:
"shhmm"
där shh är ett signerat tvåsiffrigt decimaltal i intervallet -24 till +25, och mm är ett osignerat tvåsiffrigt decimaltal i intervallet 00 till 59.
Det representerar tidszonen för tidsstämpeln som antalet timmar och minuter öster om UTC med +, eller väster om UTC med -.
Om både timmar och minuter är noll ska tecknet vara +.
Om tidszonen inte är ett helt antal minuter från UTC är zon-fältet implementationsdefinierat.
Därefter ska följande utdataformat tillämpas för varje uppsättning ändringar.
Först ska radintervallet i varje fil skrivas i följande format:
"@@ -%s +%s @@", <fil1-intervall>, <fil2-intervall>
Varje intervall-fält ska ha formen:
"%1d", <börjanradnummer>
eller:
"%1d,1", <börjanradnummer>
om intervallet innehåller exakt en rad, och annars:
"%1d,%1d", <börjanradnummer>, <antal rader>
Om ett intervall är tomt ska dess börjanradnummer vara numret på raden precis före intervallet, eller 0 om det tomma intervallet börjar filen.
Därefter ska de berörda raderna tillsammans med kontextrader skrivas.
Varje icke-tom opåverkad rad ska skrivas i följande format:
" %s", <opåverkad_rad>
där innehållet i den opåverkade raden ska tas från fil1.
Det är implementationsdefinierat om en tom opåverkad rad skrivs som en tom rad eller som en rad med ett enda mellanslag.
Denna rad representerar också samma rad i fil2, även om fil2:s rad kan ha annat innehåll på grund av flaggan -b.
Borttagna rader ska skrivas som:
"-%s", <borttagen_rad>
Tillagda rader ska skrivas som:
"+%s", <tillagd_rad>
Ordningen på raderna som skrivs ska vara densamma som i motsvarande fil.
En borttagen rad ska aldrig skrivas direkt efter en tillagd rad.
Om -U n anges ska utdata inte innehålla fler än 2n på varandra följande opåverkade rader.
Om utdata innehåller en berörd rad och denna rad ligger intill upp till n på varandra följande opåverkade rader i motsvarande fil, ska utdata innehålla dessa opåverkade rader.
Flaggan -u ska fungera som -U3.
Standardfel
Standardfel ska endast användas för diagnostiska meddelanden.
Utdatafiler
Inga.
Utökad beskrivning
Ingen.
Avslutningsstatus
Följande avslutningsvärden ska returneras:
- 0
- Inga skillnader hittades.
- 1
- Skillnader hittades.
- >1
- Ett fel inträffade.
Följder av fel
Standardbeteende.
Följande avsnitt är informativa.
Programanvändning
Om rader i slutet av en fil ändras och andra rader läggs till kan diff-utdata visa detta som en borttagning och tillägg, som en ändring, eller som en ändring och ett tillägg.
diff förväntas inte veta vad som hände, och användare bör inte bry sig om skillnaden i utdata så länge den tydligt visar skillnaderna mellan filerna.
Exempel
Om dir1 är en katalog som innehåller en katalog med namnet x, dir2 är en katalog som innehåller en katalog med namnet x, både dir1/x och dir2/x innehåller filer med namnet date.out, och dir2/x innehåller en fil med namnet y, kan kommandot:
diff -r dir1 dir2
skapa utdata som liknar:
Common subdirectories: dir1/x and dir2/x Only in dir2/x: y diff -r dir1/x/date.out dir2/x/date.out 1c1 < Mon Jul 2 13:12:16 PDT 1990 --- > Tue Jun 19 21:41:39 PDT 1990
Bakgrund
Flaggan -h utelämnades eftersom den var otillräckligt specificerad och inte förbättrar programportabilitet.
Historiska implementationer använder algoritmer som inte alltid producerar en minimal lista över skillnader. Den nuvarande formuleringen om att göra varje ansträngning är det bästa POSIX.1-2017 kan göra, eftersom det inte finns något mått som kan användas för att bedöma implementationers kvalitet mot alla tänkbara filinnehåll.
Påståendet ”Denna lista bör vara minimal” innebär tydligt att implementationer inte förväntas ge följande utdata när två filer med 100 rader jämförs och endast skiljer sig med ett tecken på en enda rad:
1,100c1,100 alla 100 rader från fil1 föregångna av "< " --- alla 100 rader från fil2 föregångna av "> "
Meddelandena Only in som krävs när flaggan -r anges används inte av de flesta historiska implementationer om flaggan -e också anges. De krävs här eftersom de ger användbar information som måste tillhandahållas för att uppdatera en målkataloghierarki så att den matchar en källhierarki.
Meddelandena Common subdirectories skrivs av System V och 4.3 BSD när flaggan -r anges. De är tillåtna här men krävs inte, eftersom de rapporterar något som är samma, inte en skillnad, och inte behövs för att uppdatera en målhierarki.
Flaggan -c, som skriver utdata i ett format med kontextrader, har tagits med. Formatet är användbart av flera skäl, bland annat förbättrad läsbarhet och möjligheten att förstå skillnader när målfilen har radnummer som skiljer sig från en annan liknande men något annorlunda kopia.
Verktyget patch är mest värdefullt när det arbetar med skillnadslistor i kontextformat.
BSD-versionen av -c tar ett valfritt argument som anger mängden kontext. I stället för att överbelasta -c och bryta Utility Syntax Guidelines för diff beslutade standardutvecklarna att lägga till en separat flagga för att ange en kontext-diff med en viss mängd kontext, nämligen -C.
Formatet för kontext-diffar utökades också något i 4.3 BSD för att tillåta att flera ändringar som ligger inom kontextrader från varandra slås samman. Utdataformatet innehåller ytterligare fyra asterisktecken efter intervallet av berörda rader i den första filen. Detta gjordes för att ge en markering för gamla program, som äldre versioner av patch, som endast förstår det gamla kontextformatet.
Versionen av kontextformatet som beskrivs här kräver inte att flera ändringar inom kontextrader slås samman, men förbjuder det inte heller.
Utökningen är uppåtkompatibel, så leverantörer som vill behålla den gamla versionen av diff kan göra det genom att lägga till de extra fyra asterisktecknen. Verktyg som för närvarande använder diff och förstår det nya sammanslagna formatet förstår också det gamla osammanslagna formatet, men inte tvärtom.
Flaggorna -u och -U från GNU diff har tagits med. Deras utdataformat, utformat av Wayne Davison, tar mindre plats än -c- och -C-formatet och är i många fall lättare att läsa.
Formatets tidsstämplar varierar inte med lokal, så LC_TIME påverkar det inte.
Formatets radnummer renderas med formatet %1d, inte %d, eftersom reglerna för filformatsnotation skulle tillåta extra blanktecken runt numren.
Substitutionskommandot lades till som ett ytterligare format för flaggan -e. Detta gjordes för att ge implementationer ett sätt att åtgärda den klassiska buggen med en ensam punkt på en rad, som finns i många versioner av diff.
Eftersom många implementationer har åtgärdat denna bugg beslutade standardutvecklarna att inte standardisera trasigt beteende, utan i stället tillhandahålla verktyget som krävs för att åtgärda buggen.
Ett sätt att åtgärda buggen är att skriva ut två punkter när en ensam punkt behövs, sedan avsluta append-kommandot med en punkt och därefter använda substitutionskommandot för att omvandla de två punkterna till en punkt.
Den BSD-härledda flaggan -r lades till för att ge en mekanism för att använda diff för att jämföra två filsystemträd. Detta beteende är användbart, är standardpraxis på alla BSD-härledda system och kan inte enkelt reproduceras med verktyget find.
Kravet att diff inte ska jämföra filer under vissa omständigheter, även om de har samma namn, baseras på faktisk utdata från historiska implementationer. Det specificerade beteendet undviker problem som uppstår när man stöter på FIFO:er och andra filer som skulle få diff att hänga medan det väntar på indata, utan någon indikation till användaren om att diff har hängt sig.
En tidigare version av denna standard specificerade utdataformatet mer exakt, men i praktiken ignorerades detta krav i stor utsträckning och fördelen med standardisering verkade liten. Därför är det nu ospecificerat.
Vid vanlig användning bör:
diff -r
indikera skillnader i filhierarkier, inte skillnader i innehållet hos enheter som pekas ut av hierarkierna.
Många tidiga implementationer av diff kräver sökbara filer. Eftersom POSIX.1-2017, System Interfaces, stöder namngivna rör ansåg standardutvecklarna att en sådan begränsning var orimlig.
Observera också att det tillåtna filnamnet - nästan alltid hänvisar till ett rör.
Ingen katalogsökningsordning anges för diff. Den historiska ordningen är i själva verket inte optimal, eftersom den skriver ut alla skillnader på aktuell nivå, inklusive meddelanden om alla gemensamma underkataloger, innan den rekursivt går in i dessa underkataloger.
Meddelandet:
"diff %s %s %s\n", <diff-flaggor>, <filnamn1>, <filnamn2>
varierar inte med lokal eftersom det är representationen av ett kommando, inte en engelsk mening.
Framtida riktning
Ingen.
Se även
- cmp(1p)
- comm(1p)
- ed(1p)
- find(1p)
- POSIX.1-2017, Base Definitions, kapitel 8, Environment Variables
- POSIX.1-2017, Base Definitions, avsnitt 12.2, Utility Syntax Guidelines
Upphovsrätt
Delar av denna text är återgivna och reproducerade i elektronisk form från:
- IEEE Std 1003.1-2017, Standard for Information Technology -- Portable Operating System Interface (POSIX)
- The Open Group Base Specifications Issue 7, 2018 Edition
Copyright © 2018 Institute of Electrical and Electronics Engineers, Inc. och The Open Group.
Vid avvikelse mellan denna version och den ursprungliga IEEE- och The Open Group-standarden gäller den ursprungliga standarden som referensdokument.
Den ursprungliga standarden kan hämtas online från:
Eventuella typografiska fel eller formateringsfel på denna sida har troligen införts vid konverteringen av källfilerna till man-sideformat.
För att rapportera sådana fel, se: