İki dosya nasıl karşılaştırılır


83

Yani temelde yapmak istediğim iki dosyayı satır 2 sütunla karşılaştırmak. Bunu nasıl başarabilirim?

File_1.txt:

User1 US
User2 US
User3 US

File_2.txt:

User1 US
User2 US
User3 NG

Çıktı dosyası:

User3 has changed

11
Kullanındiff "File_1.txt" "File_2.txt"
Pandya

Ayrıca ziyaret edin: askubuntu.com/q/12473
Pandya

Yanıtlar:


92

diffKomuta bak . Bu iyi bir araç ve man diffterminalinize yazarak her şeyi okuyabilirsiniz .

Yapmak isteyeceğiniz komut diff File_1.txt File_2.txt, ikisi arasındaki farkı ortaya çıkaran ve şöyle görünmesi gereken şeydir:

görüntü tanımını buraya girin

Çıktıyı üçüncü komuttan okumakla ilgili kısa bir not: 'oklar' ( <ve >), satırın değerinin sol dosyada ( <) vs sağ dosyada ( >) olduğunu belirtir ; sol dosyada girdiğiniz dosyadır. ilk önce komut satırında, bu durumdaFile_1.txt

Ek olarak dördüncü komutun diff ... | tee Output_Filebu sonucu bir a'ya diffdönüştürdüğünü farkedebilirsiniz, teebu çıktıyı bir dosyaya koyar, böylece daha sonra o anda konsolda görüntülemek istemiyorsanız daha sonraya kaydedebilirsiniz.


Bu başka dosyalar yapabilir mi (görüntüler gibi)? Yoksa sadece belgelerle mi sınırlı?
Gregory Opera,

2
Bildiğim kadarıyla, metin dosyaları ile sınırlı. Kod esasen metin olduğu için çalışacaktır, ancak herhangi bir ikili dosya (hangi resimler) sadece önemsizleşecektir. Onların yaparak özdeş olmadığını görme karşılaştırmak CAN: diff file1 file2 -s. İşte bir örnek: imgur.com/ShrQx9x
Mitch

Çıktıyı renklendirmenin bir yolu var mı? Ben sadece CLI tutmak istiyorum, ama biraz daha ... insan dokunuşuyla.
Lazar Ljubenović

36

Veya Meld Diff kullanabilirsiniz

Meld, dosyaları, dizinleri ve sürüm denetimli projeleri karşılaştırmanıza yardımcı olur. Hem dosyaların hem de dizinlerin iki ve üç yönlü karşılaştırmasını sağlar ve birçok popüler sürüm kontrol sistemi için destek sağlar.

Çalıştırarak yükleyin:

sudo apt-get install meld

Senin örnek:

görüntü tanımını buraya girin

Dizini karşılaştır:

görüntü tanımını buraya girin

Metin dolu bir örnek:

görüntü tanımını buraya girin


18

Vimdiff kullanabilirsiniz .

Örnek:

vimdiff  file1  file2

1
bu bir renk var
Jake Toronto

Bu, ilk dosyamın satır sonunun dosve ikincinin de olduğunu gösterdiği için bana yardımcı oldu unix.
LoMaPh

13

FWIW, diff'den yan yana çıktı almayı tercih ederim

diff -y -W 120 File_1.txt File_2.txt

gibi bir şey verecekti:

User1 US                            User1 US
User2 US                            User2 US
User3 US                          | User3 NG

10

Komutu kullanabilirsiniz cmp:

cmp -b "File_1.txt" "File_2.txt"

çıktı

a b differ: byte 25, line 3 is 125 U 116 N

cmpdiffİstediğiniz tüm dönüş kodu ise çok daha hızlı .
stevesliva

8

Meldgerçekten harika bir araçtır. Ancak, diffuseiki dosyayı görsel olarak karşılaştırmak için de kullanabilirsiniz :

diffuse file1.txt file2.txt

görüntü tanımını buraya girin


7

Litteraly soruya yapışarak (dosya1, dosya2, çıktı dosyası "değişmiş" mesajı ile) aşağıdaki betiği çalışır.

Komut dosyasını boş bir dosyaya kopyalayın, kaydedin compare.py, çalıştırılabilir duruma getirin, komutla çalıştırın:

/path/to/compare.py <file1> <file2> <outputfile>

Senaryo:

#!/usr/bin/env python

import sys
file1 = sys.argv[1]; file2 = sys.argv[2]; outfile = sys.argv[3]

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

with open(outfile, "wt") as out:
    for line in mismatch:
        out.write(line+" has changed"+"\n")

Birkaç ekstra satırla, çıktı dosyasının tanımlanmasına bağlı olarak, bir çıktı dosyasına veya terminale yazdırmasını sağlayabilirsiniz:

Bir dosyaya yazdırmak için:

/path/to/compare.py <file1> <file2> <outputfile>

Terminal penceresine yazdırmak için:

/path/to/compare.py <file1> <file2> 

Senaryo:

#!/usr/bin/env python

import sys

file1 = sys.argv[1]; file2 = sys.argv[2]
try:
    outfile = sys.argv[3]
except IndexError:
    outfile = None

def readfile(file):
    with open(file) as compare:
        return [item.replace("\n", "").split(" ") for item in compare.readlines()]

data1 = readfile(file1); data2 = readfile(file2)
mismatch = [item[0] for item in data1 if not item in data2]

if outfile != None:
        with open(outfile, "wt") as out:
            for line in mismatch:
                out.write(line+" has changed"+"\n")
else:
    for line in mismatch:
        print line+" has changed"

4

colordiffGibi davranan diffancak çıktısını renklendiren kullanımı kolay bir yöntemdir . Bu farkları okumak için çok yararlıdır. Örneğinizi kullanarak

$ colordiff -u File_1.txt File_2.txt
--- File_1.txt  2016-12-24 17:59:17.409490554 -0500
+++ File_2.txt  2016-12-24 18:00:06.666719659 -0500
@@ -1,3 +1,3 @@
 User1 US
 User2 US
-User3 US
+User3 NG

nerede useçenek birleşik diff verir. Bu renklendirilmiş farkın nasıl göründüğü:

görüntü tanımını buraya girin

Yükleme colordiffçalıştırarak sudo apt-get install colordiff.


1
Renkleri istiyorsanız ben vim yerleşik fark aslında Mr.S tarafından cevap olarak, kullanımı kolay olacak şekilde bulmak
thomasrutter

2

Ek cevap

Dosyaların hangi bölümlerinin farklı olduğunu bilmeye gerek yoksa, dosyanın sağlama toplamını kullanabilirsiniz. Bunu yapmak için md5sumveya kullanarak birçok yol var sha256sum. Temel olarak, her biri bir dosyanın içeriğinin karma olduğu bir dizge çıkarır. İki dosya aynıysa, karma değerleri de aynı olacaktır. Bu, genellikle Ubuntu kurulum iso görüntüleri gibi bir yazılımı indirirken kullanılır. Genellikle indirilen içeriğin bütünlüğünü doğrulamak için kullanılır.

İki dosyayı argüman olarak verebileceğiniz komut dosyasını aşağıda düşünün ve dosya aynı olup olmadığını söyleyecektir.

#!/bin/bash

# Check if both files exist  
if ! [ -e "$1"  ];
then
    printf "%s doesn't exist\n" "$1"
    exit 2
elif ! [ -e "$2" ]
then
    printf "%s doesn't exist\n" "$2"
    exit 2
fi

# Get checksums of eithe file
file1_sha=$( sha256sum "$1" | awk '{print $1}')
file2_sha=$( sha256sum "$2" | awk '{print $1}')

# Compare the checksums
if [ "x$file1_sha" = "x$file2_sha" ]
then
    printf "Files %s and %s are the same\n" "$1" "$2"
    exit 0
else
    printf "Files %s and %s are different\n" "$1" "$2"
    exit 1
fi

Örnek çalışma:

$ ./compare_files.sh /etc/passwd ./passwd_copy.txt                                                                
Files /etc/passwd and ./passwd_copy.txt are the same
$ echo $?
0
$ ./compare_files.sh /etc/passwd /etc/default/grub                                                                
Files /etc/passwd and /etc/default/grub are different
$ echo $?
1

Daha eski cevap

Buna ek olarak comm, iki sıralı dosyayı karşılaştıran ve 3 sütunda çıktı veren bir komut var : dosya # 1'e özgü öğeler için sütun 1, dosya # 2'ye özgü öğeler için sütun 2 ve her iki dosyada bulunan öğeler için sütun 3.

Her iki sütunu da bastırmak için -1, -2 ve -3 anahtarlarını kullanabilirsiniz. -3 kullanımı farklı satırları gösterecektir.

Kumandanın ekran görüntüsünü çalışırken görebilirsiniz.

görüntü tanımını buraya girin

Tek bir gereksinim var - dosyalar düzgün şekilde karşılaştırılmak üzere sıralanmalı. sortkomut bu amaç için kullanılabilir. Körük, dosyaların sıralanıp karşılaştırıldığı başka bir ekran görüntüsüdür. Sol bellekte yalnızca File_1 ile başlayan, 2 numaralı sütundan başlayan çizgiler yalnızca File_2'ye aittir.

görüntü tanımını buraya girin


Mobil :) gerçi, şimdi Done üzerine düzenlersiniz biraz zor oluyor @DavidFoerster
Sergiy Kolodyazhnyy

2

Git yükleyin ve kullanın

$ git diff filename1 filename2

Ve renkli formatta çıktılar alacaksınız

Git kurulumu

$ apt-get update
$ apt-get install git-core

2

colcmp.sh

İsim / değer çiftlerini formattaki 2 dosyada karşılaştırır name value\n. Değiştirilirse , nameyerine yazar Output_file. İlişkisel diziler için bash v4 + gerektirir .

kullanım

$ ./colcmp.sh File_1.txt File_2.txt
User3 changed from 'US' to 'NG'
no change: User1,User2

Çıktı dosyası

$ cat Output_File
User3 has changed

Kaynak (colcmp.sh)

cmp -s "$1" "$2"
case "$?" in
    0)
        echo "" > Output_File
        echo "files are identical"
        ;;
    1)
        echo "" > Output_File
        cp "$1" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array1.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.array1.tmp.sh
        chmod 755 ~/.colcmp.array1.tmp.sh
        declare -A A1
        source ~/.colcmp.array1.tmp.sh

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

        USERSWHODIDNOTCHANGE=
        for i in "${!A1[@]}"; do
            if [ "${A2[$i]+x}" = "" ]; then
                echo "$i was removed"
                echo "$i has changed" > Output_File
            fi
        done
        for i in "${!A2[@]}"; do
            if [ "${A1[$i]+x}" = "" ]; then
                echo "$i was added as '${A2[$i]}'"
                echo "$i has changed" > Output_File
            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then
                echo "$i changed from '${A1[$i]}' to '${A2[$i]}'"
                echo "$i has changed" > Output_File
            else
                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"
            fi
        done
        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
        ;;
    *)
        echo "error: file not found, access denied, etc..."
        echo "usage: ./colcmp.sh File_1.txt File_2.txt"
        ;;
esac

açıklama

Anladığım kadarıyla kodun ve ne anlama geldiğinin dağılması. Düzenlemelerden ve önerilerinizden memnuniyet duyarım.

Temel Dosya Karşılaştırma

cmp -s "$1" "$2"
case "$?" in
    0)
        # match
        ;;
    1)
        # compare
        ;;
    *)
        # error
        ;;
esac

cmp $ değerini ayarlayacak ? olarak aşağıda :

  • 0 = dosya eşleşmesi
  • 1 = dosyalar farklı
  • 2 = hata

Ben bir dava kullanmayı seçtim .. $ değerlendirmek için esac deyimi ? Çünkü değeri $? test ([) dahil olmak üzere her komuttan sonra değişir .

Alternatif olarak $? Değerini tutmak için bir değişken kullanabilirdim ? :

cmp -s "$1" "$2"
CMPRESULT=$?
if [ $CMPRESULT -eq 0 ]; then
    # match
elif [ $CMPRESULT -eq 1 ]; then
    # compare
else
    # error
fi

Yukarıdaki durum ifadesiyle aynı şeyi yapar. Daha çok sevdiğim IDK.

Çıkışı Temizle

        echo "" > Output_File

Yukarıdaki çıktı dosyasını temizler, böylece hiçbir kullanıcı değişmezse, çıktı dosyası boştur.

İçeriye bunu dava böylece ifadeleri çıkış_dosyası hatası değişmeden kalır.

Kullanıcı Dosyasını Kabuk Betiğine Kopyala

        cp "$1" ~/.colcmp.arrays.tmp.sh

Yukarıda, File_1.txt dosyasını geçerli kullanıcının ana dizinine kopyalar .

Örneğin, geçerli kullanıcı john ise yukarıdakiler cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh ile aynı olacaktır.

Özel Karakterlerden Kaçış

Temel olarak paranoyak oldum. Bu karakterlerin değişken atamanın bir parçası olarak bir komut dosyasında çalıştırıldığında özel bir anlamı olabileceğini veya harici bir program yürütebileceğini biliyorum:

  • `- back-tick - bir program yürütür ve çıktı, komut dosyanızın bir parçasıymış gibi çıkar
  • $ - dolar işareti - genellikle bir değişkene önek ekler
  • $ {} - daha karmaşık değişken ikamesi sağlar
  • $ () - idk bu ne yapar ama kod yürütebileceğini düşünüyorum

Ne bilmiyorum ben bash bilmem ne kadar olduğunu. Başka hangi karakterlerin özel bir anlamı olabileceğini bilmiyorum, ama hepsinden ters eğik çizgi ile kaçmak istiyorum:

        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array1.tmp.sh

sed , normal ifade deseni eşleştirmesinden çok daha fazlasını yapabilir. "S / (find) / (replace) /" komut dosyasıözellikle desen eşleşmesini gerçekleştirir.

"S / (bulmak) / (replace) / (modifiye)"

türkçe: herhangi bir noktalama işaretini veya özel grup karakterini yakalama grubu 1 (\\ 1) olarak yakalayın

  • (değiştir) = \\ 1
    • \\\\ = değişmez karakter (\\) yani ters eğik çizgi
    • \\ 1 = grup 1 yakala

İngilizce: tüm özel karakterleri ters eğik çizgiyle önekleyin

  • (değiştiriciler) = g
    • g = global olarak değiştir

İngilizce: Eğer aynı satırda birden fazla maç bulunursa, hepsini değiştirin

Tüm Komut Dosyasını Yorumlayın

        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.arrays.tmp.sh

Yukarıdaki her ~ / .colcmp.arrays.tmp.sh satırının bir bash yorum karakteriyle ( # ) öneklenmesi için normal ifade kullanır . Daha sonra ben yürütmek niyetinde çünkü bunu ~ / .colcmp.arrays.tmp.sh kullanarak kaynak ben emin tüm biçimi için bilmiyorum çünkü komutu ve File_1.txt .

Yanlışlıkla rastgele kod çalıştırmak istemiyorum. Kimsenin bildiğini sanmıyorum.

"S / (bulmak) / (replace) /"

türkçe: her satırı "caputure group 1" (\\ 1) olarak yakalayın

  • (değiştir) = # \\ 1
    • # = değişmez karakter (#), bir sayı simgesi veya karma
    • \\ 1 = grup 1 yakala

türkçe: her satırı bir pound sembolüyle ve ardından değiştirilen satırla değiştirin

Kullanıcı değerini A1'e çevir [Kullanıcı] = "değer"

        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A1\\[\\1\\]=\"\\2\"/" ~/.colcmp.arrays.tmp.sh

Yukarıda bu betiğin çekirdeği var.

  • bunu dönüştür: #User1 US
    • buna: A1[User1]="US"
    • veya bu: A2[User1]="US"(2. dosya için)

"S / (bulmak) / (replace) /"

İngilizcede:

  • gerektirir ancak baştaki yorum karakterlerini yoksay (#)
  • önde gelen boşlukları yoksay
  • ilk sözcüğü grup 1 olarak yakala (\\ 1)
  • boşluk gerektirir (veya sekme veya boşluk)
    • bu eşittir işareti ile değiştirilir çünkü
    • herhangi bir yakalama grubunun bir parçası değil ve
    • (değiştirme) modeli, yakalama grubu 1 ile yakalama grubu 2 arasına eşit bir işaret koyar.
  • hattın kalanını yakalama grubu 2 olarak yakala

  • (değiştir) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"

    • A1 \\ [- A1[denilen dizideki dizi atamasını başlatmak için hazır karakterA1
    • \\ 1 = yakalama grubu 1 - baştaki karma (#) içermez ve baştaki boşluk içermez - bu durumda yakalama grubu 1, bash ilişkisel dizisindeki ad / değer çiftinin adını ayarlamak için kullanılır.
    • \\] = \ "= değişmez karakterler ]="
      • ]= dizi atamasını kapat, örneğin, A1[User1 ]="US"
      • = = atama operatörü örneğin değişken = değer
      • " = boşlukları yakalamak için alıntı değeri ... bunun hakkında düşünmeme rağmen, yukarıdaki kodun her şeyi ters eğik çizgiye, ayrıca ters eğik çizgi karakterlerine de bırakmak daha kolay olurdu.
    • \\ 1 = grup 2 yakalama - bu durumda, ad / değer çiftinin değeri
    • "= boşluk yakalamak için teklif değerini kapatma

Türkçe: formattaki her satırı, formattaki #name valuebir dizi atama operatörüyle değiştirin.A1[name]="value"

Çalıştırılabilir Yap

        chmod 755 ~/.colcmp.arrays.tmp.sh

Yukarıdaki dizi komut dosyası çalıştırılabilir hale getirmek için chmod kullanır .

Bunun gerekli olup olmadığından emin değilim.

İlişkisel Dizi Bildirimi (bash v4 +)

        declare -A A1

Başkent -A, bildirilen değişkenlerin ilişkisel diziler olacağını gösterir .

Bu yüzden komut dosyası bash v4 veya üstü gerektirir.

Dizi Değişken Atama Komut Dosyamızı yürütün

        source ~/.colcmp.arrays.tmp.sh

Bizde zaten var:

  • dosyamızı satırdan User valuesatırına çevirdik A1[User]="value",
  • çalıştırılabilir yaptı (belki) ve
  • A1'i bir ilişkisel dizi olarak ilan etti ...

Yukarıdaki komut dosyasını mevcut kabukta çalıştırmak için kaynaklıyoruz . Bunu yaparız, böylece kod tarafından ayarlanan değişken değerlerini koruyabiliriz. Komut dosyasını doğrudan çalıştırırsanız, yeni bir kabuk oluşturur ve yeni kabuk çıkarken değişken değerler kaybolur veya en azından benim anlayışım budur.

Bu Bir İşlev Olmalı

        cp "$2" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/([^A-Za-z0-9 ])/\\\\\\1/g" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^(.*)$/#\\1/" ~/.colcmp.array2.tmp.sh
        sed -i -E "s/^#\\s*(\\S+)\\s+(\\S.*?)\\s*\$/A2\\[\\1\\]=\"\\2\"/" ~/.colcmp.array2.tmp.sh
        chmod 755 ~/.colcmp.array2.tmp.sh
        declare -A A2
        source ~/.colcmp.array2.tmp.sh

Biz aynı şeyi $ 1 ve A1 biz yapmak 2 $ ve A2 . Gerçekten bir fonksiyon olmalı. Bence bu noktada bu senaryo yeterince kafa karıştırıcı ve işe yarıyor, bu yüzden onu düzeltmeyeceğim.

Kaldırılan Kullanıcıları Algıla

        for i in "${!A1[@]}"; do
            # check for users removed
        done

İlişkisel dizi tuşlarıyla döngüler yukarıda

            if [ "${A2[$i]+x}" = "" ]; then

Yukarıda, sıfır uzunluklu bir dizeye açıkça ayarlanmış bir değişkene karşı kümelenmemiş bir değer arasındaki farkı saptamak için değişken değiştirme kullanılır.

Görünüşe göre, bir değişkenin ayarlanmış olup olmadığını görmek için birçok yol vardır . En oyu olanı seçtim.

                echo "$i has changed" > Output_File

Üstü kullanıcıyı ekler i $ için çıkış_dosyası

Eklenen veya Değiştirilen Kullanıcıları Algıla

        USERSWHODIDNOTCHANGE=

Yukarıdaki bir değişkeni temizler, böylece değişmeyen kullanıcıları takip edebiliriz.

        for i in "${!A2[@]}"; do
            # detect users added, changed and not changed
        done

İlişkisel dizi tuşlarıyla döngüler yukarıda

            if ! [ "${A1[$i]+x}" != "" ]; then

Yukarıda, bir değişkenin ayarlanmış olup olmadığını görmek için değişken ikamesi kullanılır .

                echo "$i was added as '${A2[$i]}'"

Çünkü $ i dizi anahtarı (kullanıcı adı) $ A2, [$ i] güncel kullanıcı ile ilişkili değer döndürmelidir File_2.txt .

Örneğin, $ i olan Kullanıcı1 yukarıdaki gibi okur $ {A2 [USER1]}

                echo "$i has changed" > Output_File

Üstü kullanıcıyı ekler i $ için çıkış_dosyası

            elif [ "${A1[$i]}" != "${A2[$i]}" ]; then

Çünkü $ i dizi anahtarı (kullanıcı adı) $ A1 [$ i] güncel kullanıcı ile ilişkili değer döndürmelidir File_1.txt ve $ A2 [$ i] değeri döndürmelidir File_2.txt .

Yukarıdaki $ i kullanıcısı için ilişkili değerleri her iki dosyadan da karşılaştırır.

                echo "$i has changed" > Output_File

Üstü kullanıcıyı ekler i $ için çıkış_dosyası

                if [ x$USERSWHODIDNOTCHANGE != x ]; then
                    USERSWHODIDNOTCHANGE=",$USERSWHODIDNOTCHANGE"
                fi
                USERSWHODIDNOTCHANGE="$i$USERSWHODIDNOTCHANGE"

Yukarıda, değişmeyen kullanıcıların virgülle ayrılmış bir listesi oluşturulur. Listede boşluk olmadığına veya bir sonraki kontrolün alıntı yapılması gerekeceğine dikkat edin.

        if [ x$USERSWHODIDNOTCHANGE != x ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi

Yukarıdaki $ USERSWHODIDNOTCHANGE’ın değerini ancak yalnızca USERSWHODIDNOTCHANGE’de bir değer varsa bildirir . Bunun yazıldığı gibi $ USERSWHODIDNOTCHANGE boşluk bırakamaz . Boşluk gerektiriyorsa, yukarıdaki gibi yeniden yazılabilir:

        if [ "$USERSWHODIDNOTCHANGE" != "" ]; then
            echo "no change: $USERSWHODIDNOTCHANGE"
        fi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.