Ero
Laskennassa diff on tiedostojen vertailuapuohjelma, joka näyttää eron kahden tiedoston välillä. Tämä ohjelma tulostaa rivi riviltä tiedostoon tehdyt muutokset (tekstitiedostoille). Nykyaikaiset toteutukset tukevat myös binääriä . Apuohjelman tulostetta kutsutaan "diff"ksi tai yleisemmin korjaustiedostoksi , koska sitä voidaan käyttää korjaustiedoston kanssa . Muiden tiedostojen vertailuapuohjelmien tulosta kutsutaan usein myös nimellä "diff".
Historia
Diff-apuohjelma kehitettiin 1970-luvun alussa Unix -käyttöjärjestelmää varten , joka oli AT&T Bell Labsin tekemä Murray Hillissä, New Jerseyssä. Lopullisen version, joka jaettiin Unix 5:llä vuonna 1974, kirjoitti kokonaan Douglas McIlroy .
McIlroyn työtä edelsi ja vaikutti Steve Johnsonin GECOS-vertailuohjelma ja Mike Leskin proof-ohjelma. Todistus on myös peräisin Unixista ja, kuten diff, teki rivi riviltä muutoksia ja jopa käytti kulmasulkuja (">" ja "<") kuvaamaan rivin lisäyksiä ja poistoja ohjelman ulostulossa. Näissä varhaisissa sovelluksissa käytettyä heuristiikkaa pidettiin kuitenkin epäluotettavina. Vertailutyökalun mahdollinen käyttökelpoisuus sai McIlroyn tutkimaan ja kehittämään tehokkaamman työkalun, jota voitaisiin käyttää useissa eri tehtävissä, mutta joka toimisi hyvin PDP-11-laitteiston käsittely- ja kokorajoitusten puitteissa. Hänen lähestymistapansa ongelmaan oli seurausta yhteistyöstä Bell Labsin ihmisten kanssa, mukaan lukien Alfred Ahon, Elliot Pinsonin, Jeffrey Ullmanin ja Harold S. Stonen kanssa.
Algoritmi
Diff:n toiminta perustuu pisimmän yhteisen osasekvenssin löytämiseen ( LCS-ongelma) . Esimerkiksi elementtejä on kaksi sarjaa:
abcdfghjqz
abcdefgijkrxyz
ja sinun on löydettävä pisin elementtisarja, joka esitetään molemmissa sarjoissa samassa järjestyksessä. Tämä tarkoittaa, että on löydettävä uusi sekvenssi, joka voidaan saada ensimmäisestä sekvenssistä poistamalla joitakin elementtejä tai toisesta sekvenssistä poistamalla muita elementtejä. Tässä tapauksessa järjestys on
abcdfgjz
Kun olet saanut suurimman yhteisen sekvenssin, on jäljellä vain pieni askel ennen erotuskaltaisen lähdön saamista:
ehikqrxy
+ - + + - + + +
Käyttö
diff kutsutaan komentoriviltä kahden tiedoston nimellä argumentteina: diff original new . Komennon tulos on muutokset, jotka on tehtävä alkuperäiseen lähdetiedostoon, jotta uusi tiedosto saadaan uutena. Jos alkuperäinen ja uusi ovat hakemistoja, diff-tunnusta käytetään automaattisesti jokaiseen tiedostoon, joka on olemassa molemmissa hakemistoissa. Kaikki tämän artikkelin esimerkit käyttävät seuraavia kahta tiedostoa, alkuperäistä ja uutta :
|
alkuperäinen: Tämä osa asiakirjaa
pysyi ennallaan
versiosta toiseen. Jos
hänessä ei ole muutosta
ei pitäisi näyttää.
Muuten se ei auta
optimaalisen johtopäätös
tuotettu
muutoksia.
Tämä kappale sisältää
vanhentunutta tekstiä.
Se poistetaan
pian.
Tämä asiakirja
täytyy olla
oikeinkirjoituksen tarkistus.
Toisaalta virhe
Sanalla sanoen - ei maailmanloppu.
Loput kappaleesta
ei vaadi muutoksia.
Uusi teksti voi
lisää asiakirjan loppuun.
|
Uusi: Tämä on tärkeä huomio!
Siksi sen pitäisi
sijaita
tämän alussa
asiakirja!
Tämä osa asiakirjaa
pysyi ennallaan
versiosta toiseen. Jos
hänessä ei ole muutosta
ei pitäisi näyttää.
Muuten se ei auta
optimaalisen johtopäätös
tiedon määrä.
Tämä asiakirja
täytyy olla
oikeinkirjoituksen tarkistus.
Toisaalta virhe
Sanalla sanoen - ei maailmanloppu.
Loput kappaleesta
ei vaadi muutoksia.
Uusi teksti voi
lisää asiakirjan loppuun.
Tämä kappale sisältää
tärkeitä lisäyksiä
tälle asiakirjalle.
|
Diff alkuperäinen uusi komento tuottaa seuraavan normaalin diff - ulostulon : 0a1.6
> Tämä on tärkeä huomio!
> Siksi pitäisi
> sijaita
> tämän alussa
> asiakirja!
>
8.14c14
<tuotannon määrä
<muutoksia.
<
< Tämä kappale sisältää
< vanhentunutta tekstiä.
< Se poistetaan
< lähitulevaisuudessa.
---
> tiedon määrä.
17c17
< täytyy tehdä
---
> täytyy tehdä
24-25.28
>
> Tämä kappale sisältää
> tärkeitä lisäyksiä
> tälle asiakirjalle.
|
Tässä perinteisessä tulostusmuodossa a tarkoittaa lisättyä ( englanninkielisestä add ), d tarkoittaa poistettua , c tarkoittaa muutettua . Kirjaimia a, d tai c edeltävät lähdetiedoston rivinumerot, joita seuraa kohdetiedoston rivinumerot. Jokaista lisättyä, poistettua tai muokattua riviä edeltää kulmasulkeet .
Oletusarvoisesti lähde- ja kohdetiedostoille yhteisiä rivinumeroita ei ole määritetty. Siirretyt rivit näytetään lisättyinä uuteen sijaintiinsa ja poistettuina aiemmasta sijainnistaan. [yksi]
Vaihtoehdot
Useimmat diff-toteutuksista ovat pysyneet ulkoisesti muuttumattomina vuodesta 1975 lähtien. Muutokset sisältävät parannuksia pääalgoritmiin, uusien komentonäppäinten lisäämisen ja uudet tulostusmuodot. Perusalgoritmi on hahmoteltu Eugene W. Myersin teoksissa An O(ND) Difference Algorithm ja sen variaatiot [2] ja Webb Millerin ja Myersin [3] A File Comparison Program -ohjelmassa . Algoritmi on itsenäisesti keksitty ja kuvattu E. Ukkosen julkaisussa Algorithms for Approximate String Matching [4] . Diff-ohjelman ensimmäiset versiot suunniteltiin vertaamaan tekstitiedostojen rivejä käyttämällä rivinvaihtomerkkiä rivierottimena. 1980-luvulla binääritiedostojen tuki johti muutoksiin ohjelman toiminnassa ja toteutuksessa.
Muokkaa skriptiä
Muokkauskomentosarja voidaan luoda nykyaikaisilla diff-versioilla valitsimella -e . Esimerkkimme tulos näyttää tältä:
24a Tämä kappale sisältää tärkeitä lisäyksiä tälle asiakirjalle. . 17c täytyy olla . 8.14c tiedon määrä. . 0a Tämä on tärkeä huomio! Siksi sen pitäisi sijaita tämän alussa asiakirja! .
Jos haluat käyttää tuloksena saatua komentosarjaa muuntaaksesi alkuperäisen tiedoston uuteen tiedoston tilaan , meidän on lisättävä kaksi riviä skriptin loppuun: toinen sisältää komennon w (kirjoita), toinen - q (sulje). Esimerkiksi niin . Tässä olemme nimenneet diff-tiedoston mydiff . Muutos tapahtuu, kun annamme komennon .
printf "w\nq\n" >> mydiffed -s original < mydiff
Kontekstimuoto
BSD - versio 2.8 (julkaistu heinäkuussa 1981) esitteli kontekstimuodon ( -c ) ja mahdollisuuden kulkea rekursiivisesti tiedostojärjestelmän hakemistopuussa ( -r ).
Kontekstimuodossa muuttuneet rivit näytetään yhdessä muuttumattomien rivien kanssa ennen ja jälkeen muutettua fragmenttia. Lisäämällä kuinka monta riviä ei vaikuta, saadaan korjaustiedoston konteksti . Konteksti , joka koostuu koskemattomista riveistä, toimii viitteenä määritettäessä muokattavan fragmentin sijaintia kohdetiedostossa, vaikka muokattujen rivien rivinumerot lähde- ja kohdetiedostoissa eivät täsmää. Kontekstimuoto on ihmisten luettavampi ja luotettavampi korjaustiedostoa asetettaessa, ja tuloste otetaan korjaustiedoston syötteeksi .
Käyttäjä voi asettaa muuttumattomien rivien määrän ennen ja jälkeen muokattua fragmenttia ja se voi olla jopa nolla, mutta yleensä oletusarvo on kolme riviä. Jos fragmentin vaikuttamattomien juovien konteksti on päällekkäinen viereisen fragmentin kanssa, diff välttää vaikuttamattomien juovien kopioimisen ja yhdistää viereiset fragmentit yhdeksi.
Alkuperäisen uuden komennon diff -c tulos on:
*** /polku/alkuperäiseen ''aikaleimaan''
--- /polku/uuteen ''aikaleimaan''
**************
*** 1,3 ****
--- 1,9 ----
+ Tämä on tärkeä huomautus!
+ Joten sen
+ pitäisi sijaita
+ tämän + asiakirjan + alussa
!
+
Tämä osa asiakirjaa
pysyi ennallaan
versiosta toiseen. Jos
**************
*** 5,20 ****
ei pitäisi näyttää.
Muuten se ei auta
optimaalisen johtopäätös
! tuotettu määrä
! muutoksia.
!
! Tämä kappale sisältää
! vanhentunutta tekstiä.
! Hänet poistetaan
! pian.
Tämä asiakirja
! täytyy olla
oikeinkirjoituksen tarkistus.
Toisaalta virhe
Sanalla sanoen - ei maailmanloppu.
--- 11.20 ----
ei pitäisi näyttää.
Muuten se ei auta
optimaalisen johtopäätös
! tiedon määrä.
Tämä asiakirja
! täytyy olla
oikeinkirjoituksen tarkistus.
Toisaalta virhe
Sanalla sanoen - ei maailmanloppu.
**************
*** 22.24 ****
--- 22.28 ----
ei vaadi muutoksia.
Uusi teksti voi
lisää asiakirjan loppuun.
++
Tämä kappale sisältää
tärkeitä lisäyksiä
+ tähän asiakirjaan.
Universaali muoto
Universaali muoto (tai unidiff ) sisältää kontekstimuotoon tehdyt tekniset parannukset, mutta tekee eron vanhan ja uuden tekstin välillä tiiviimmällä tavalla. Yleistä muotoa kutsutaan yleensä komentorivivalitsimen " -u " avulla . Tätä tulostetta käytetään usein ohjelmien korjaustiedostona . Monet projektit vaativat erityisesti, että "diffs" lähetetään heille yleisessä muodossa, mikä tekee yleisestä muodosta yleisimmän ohjelmistokehittäjien välisen vaihdon.
Universaalit kontekstidiffit kehitti ensimmäisen kerran Wayne Davison elokuussa 1990 ( unidiff esiintyy comp.sources.misc:n luvussa 14). Stallman lisäsi universaalin muototuen GNU Projectin diff-apuohjelmaan kuukautta myöhemmin, ja tämä toiminto debytoi GNU diff 1.15:ssä, joka julkaistiin tammikuussa 1991. GNU diff on sittemmin yleistänyt kontekstiformaatin mahdollistaakseen mielivaltaisen erojen muotoilun.
Yleisen muodon tiedosto alkaa samoilla kahdella rivillä kuin kontekstimuoto, paitsi että alkuperäinen tiedosto alkaa kirjaimella --- ja uusi tiedosto alkaa kirjaimella " +++ ". Niitä seuraa yksi tai useampi muutettu katkelma , jotka sisältävät rivi riviltä muutoksia tiedostoihin. Muutoksettomat rivit alkavat välilyönnillä, lisätyt rivit alkavat plusmerkillä, poistetut rivit alkavat miinusmerkillä.
Fragmentti alkaa aluetiedoilla ja sitä seuraa välittömästi lisätyt rivit, poistetut rivit ja mikä tahansa määrä kontekstirivejä. Aluetietoja ympäröi kaksinkertainen @ -merkki ja ne ketjutetaan yhdelle riville, toisin kuin kaksi riviä muodossa ( kontekstimuoto ). Aluetiedot ovat seuraavassa muodossa:
@@ -l,s +l,s @@ valinnainen osion otsikko
Aluetiedot koostuvat kahdesta osasta. Alkuperäisen tiedoston osa alkaa miinuksella ja uuden tiedoston osa plussalla. Jokainen osa on muodossa l, s , jossa l on sen rivin numero, jolla aloitamme, ja s on niiden rivien lukumäärä, joita on muutettu kunkin tiedoston nykyisessä fragmentissa (eli ensimmäisessä tapauksessa tämä on välilyönnillä ja miinuksella alkavien tulosrivien summa, toisessa - välilyönnillä ja plussalla alkavien rivien summa). Monissa GNU diff:n versioissa pilkku ja lopussa olevat s voidaan jättää pois kustakin alueesta. Tässä tapauksessa s on oletuksena 1. Huomaa, että ainoa hyödyllinen arvo l :lle yksin on ensimmäisen alueen rivinumero, muut arvot voidaan laskea erotusarvosta.
Alkuperäisen tiedoston alueen fragmentin on oltava fragmentin kaikkien kontekstien ja poistettujen (mukaan lukien muokattujen) rivien summa. Uuden tiedoston alueen fragmentin on sisällettävä fragmentin kaikkien kontekstien ja lisättyjen (mukaan lukien muokattujen) rivien summa.
Aluefragmenttia voi edeltää sen osan tai toiminnon otsikko, jonka osa fragmentti on. Tämä on yleensä hyödyllistä luettaessa itse katkelmaa. Kun luot erotusta GNU:lla, erotusotsikko määräytyy säännöllisen lausekkeen [5] avulla .
Jos riviä on muutettu, se näytetään sekä poistettuna että lisättynä. Koska poistetut ja lisätyt rivit ovat vierekkäisissä fragmenteissa, nämä rivit näytetään vierekkäin [6] . Esimerkiksi:
- Tarkista tämä asiakirja. Päällä +tarkista tämä asiakirja. Päällä
Komento diff -u alkuperäinen uusi tuottaa seuraavan tulosteen:
--- /polku/alkuperäiseen ''aikaleimaan''
+++ /polku/uuteen ''aikaleimaan''
@@ -1.3 +1.9 @@
+Tämä on tärkeä huomautus!
+Sen vuoksi sen tulisi
sijaita +asiakirjan +
alkussa
!
+
Tämä osa asiakirjaa
pysyi ennallaan
versiosta toiseen. Jos
@@ -5.16 +11.10 @@
ei pitäisi näyttää.
Muuten se ei auta
optimaalisen johtopäätös
- tehtyjen
muutosten määrä.
-
-Tämä kappale sisältää
vanhentunutta tekstiä.
-Se poistetaan
-lähitulevaisuudessa.
+ tiedon määrä.
Tämä asiakirja
- täytyy tehdä
+ täytyy tehdä
oikeinkirjoituksen tarkistus.
Toisaalta virhe
Sanalla sanoen - ei maailmanloppu.
@@ -22,3 +22,7 @@
ei vaadi muutoksia.
Uusi teksti voi
lisää asiakirjan loppuun.
++
Tämä kappale sisältää
+tärkeitä lisäyksiä
+tälle asiakirjalle.
Huomaa, että välilehtiä käytetään erottamaan tiedostonimet oikein aikaleimoista. Tämä on näkymätön näytöllä ja voi kadota, kun kopioit/liität konsolista.
Diff-muotoihin on olemassa useita muutoksia ja laajennuksia, joita eri ohjelmat käyttävät ja ymmärtävät. Esimerkiksi jotkin versionhallintajärjestelmät , kuten Subversion , määrittävät versionumeron, "työkopion" tai minkä tahansa muun kommentin eron otsikon aikaleiman lisäksi.
Joidenkin ohjelmien avulla voit luoda eroja useille eri tiedostoille ja yhdistää ne yhdeksi käyttämällä otsikkoa kullekin muutetulle tiedostolle, joka saattaa näyttää suunnilleen tältä:
Hakemisto: polku/tiedosto.cpp
Erikoistyyppisiä tiedostoja, jotka eivät pääty rivinvaihtoon, ei tueta. Unidiff-apuohjelma tai POSIX-diff-standardi eivät määrittele, kuinka tällaisia tiedostoja käsitellään (itse asiassa tämän tyyppiset tiedostot eivät ole "tekstiä" POSIX [7] -määritelmässä ).
Paikkausohjelma ei tiedä mitään diff -komennon erikoistulosteen toteutuksesta.
Katso myös
- cmp
- comm
- ero3
- Kompare
- kdiff3 Arkistoitu 29. joulukuuta 2020 Wayback Machineen
- sulautua
- Microsoftin tiedostovertailu
- rsync
- tkdiff
- wdiff - diff:n kääre, jolla voit verrata tiedostoja sanoin
- WinMerge
- xdelta - diff binääritiedostoille
- delta-koodaus
- Suurin yhteinen osasarja
- Levenshtein etäisyys
- Versionhallintajärjestelmä
Muistiinpanot
- ↑ David MacKenzie, Paul Eggert ja Richard Stallman. Tiedostojen vertailu ja yhdistäminen GNU Diffin ja Patchin kanssa . – 1997.
- ↑ E. Myers. O(ND ) -eroalgoritmi ja sen muunnelmat // Algorithmica : päiväkirja. - 1986. - Voi. 1 , ei. 2 . - s. 251-266 .
- ↑ Webb Miller ja Eugene W. Myers. Tiedostojen vertailuohjelma // Ohjelmisto - Käytäntö ja kokemus. - 1985. - T. 15 , nro 11 . - S. 1025-1040 .
- ↑ E. Ukkonen. Algoritmit likimääräiseen merkkijonosovitukseen // Tiedot ja laskenta : päiväkirja. - 1985. - Voi. 64 . - s. 100-118 .
- ↑ 2.2.3 Arkistoitujen osien erojen näyttäminen 26. toukokuuta 2013 Wayback Machinessa , GNU diffutils manual
- ↑ Unified Diff Format Arkistoitu 5. huhtikuuta 2013 Wayback Machinessa , kirjoittanut Guido van Rossum , 14. kesäkuuta 2006
- ↑ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_205 Arkistoitu 29. huhtikuuta 2013 Wayback Machine -osiossa 3.205
Linkit
- GNU diffutils -paketti, arkistoitu 11. kesäkuuta 2007 Wayback Machinessa , sisältää diff. Jaettu GNU General Public License -lisenssillä .
- diffutils for Win32 Arkistoitu 12. kesäkuuta 2007 Wayback Machinessa - osa GnuWin32 :ta
- Verkkokäyttöliittymä erotukseen Arkistoitu 14. syyskuuta 2017 Wayback Machinessa (venäjä)
- C# diff-algoritmi Arkistoitu 15. kesäkuuta 2007 Wayback Machinessa — Diff-algoritmin ja sen C# -muunnelmien lähdekoodi