So vergleichen Sie zwei Dateien

83

Im Grunde möchte ich also zwei Dateien zeilenweise in Spalte 2 vergleichen. Wie könnte ich das erreichen?

Datei_1.txt:

User1 US
User2 US
User3 US

Datei_2.txt:

User1 US
User2 US
User3 NG

Ausgabedatei:

User3 has changed
Roboman1723
quelle
11
Verwenden Siediff "File_1.txt" "File_2.txt"
Pandya
Besuchen Sie auch: askubuntu.com/q/12473
Pandya

Antworten:

92

Schau in den diffBefehl. Es ist ein gutes Werkzeug und Sie können alles darüber lesen, indem Sie man diffin Ihr Terminal tippen.

Der Befehl, den Sie ausführen möchten, gibt diff File_1.txt File_2.txtden Unterschied zwischen den beiden aus und sollte ungefähr so ​​aussehen:

Bildbeschreibung hier eingeben

Ein kurzer Hinweis zum Lesen der Ausgabe des dritten Befehls: Die Pfeile ( <und >) verweisen auf den Wert der Zeile in der linken Datei ( <) gegenüber der rechten Datei ( >), wobei die linke Datei die von Ihnen eingegebene ist in diesem Fall zuerst in der BefehlszeileFile_1.txt

Außerdem stellen Sie möglicherweise fest, dass der vierte Befehl darin besteht, diff ... | tee Output_Filedie Ergebnisse von diffin ein zu teeleiten, wodurch diese Ausgabe in eine Datei verschoben wird , sodass Sie sie für einen späteren Zeitpunkt speichern können, wenn Sie nicht alles in dieser Sekunde auf der Konsole anzeigen möchten.

Mitch
quelle
Kann dies andere Dateien (wie Bilder) tun? Oder ist es nur auf Dokumente beschränkt?
Gregory Opera
2
Soweit ich weiß, ist es auf Textdateien beschränkt. Code wird funktionieren, da es sich im Wesentlichen um Text handelt, aber alle Binärdateien (welche Bilder sind) werden einfach rausgeworfen. Sie können vergleichen , um zu sehen , ob sie tun identisch sind: diff file1 file2 -s. Hier ist ein Beispiel: imgur.com/ShrQx9x
Mitch
Gibt es eine Möglichkeit, die Ausgabe einzufärben? Ich würde es gerne nur als CLI behalten, aber mit etwas mehr ... menschlichem Touch.
Lazar Ljubenović
36

Oder Sie können Meld Diff verwenden

Mit Meld können Sie Dateien, Verzeichnisse und versionskontrollierte Projekte vergleichen. Es bietet einen Zwei- und Drei-Wege-Vergleich von Dateien und Verzeichnissen und unterstützt viele gängige Versionskontrollsysteme.

Installieren Sie, indem Sie Folgendes ausführen:

sudo apt-get install meld

Ihr Beispiel:

Bildbeschreibung hier eingeben

Verzeichnis vergleichen:

Bildbeschreibung hier eingeben

Beispiel mit vollem Text:

Bildbeschreibung hier eingeben

Achu
quelle
18

Sie können vimdiff verwenden .

Beispiel:

vimdiff  file1  file2
Frau
quelle
1
Dieser hat Farben
Jake Toronto
Dies half mir, da es zeigte, dass das Zeilenende meiner ersten Datei in dosund die zweite in war unix.
LoMaPh
13

FWIW, ich mag eher, was ich mit Side-by-Side-Ausgabe von diff bekomme

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

würde etwas geben wie:

User1 US                            User1 US
User2 US                            User2 US
User3 US                          | User3 NG
Mike Reardon
quelle
10

Sie können den Befehl verwenden cmp:

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

Ausgabe wäre

a b differ: byte 25, line 3 is 125 U 116 N
Maythux
quelle
cmpist viel schneller als diffwenn alles was Sie wollen, der Rückkehrcode ist.
Stevesliva
8

Meldist ein wirklich tolles Werkzeug. Sie können aber auch diffusezwei Dateien visuell vergleichen:

diffuse file1.txt file2.txt

Bildbeschreibung hier eingeben

Meysam
quelle
7

Wenn Sie sich an die Frage halten (Datei1, Datei2, Ausgabedatei mit der Meldung "Hat sich geändert"), funktioniert das folgende Skript.

Kopieren Sie das Skript in eine leere Datei, speichern Sie es als compare.py, machen Sie es ausführbar und führen Sie es mit dem folgenden Befehl aus:

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

Das Drehbuch:

#!/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")

Mit ein paar zusätzlichen Zeilen können Sie es entweder in eine Ausgabedatei oder auf das Terminal drucken lassen, je nachdem, ob die Ausgabedatei definiert ist:

So drucken Sie in eine Datei:

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

So drucken Sie in das Terminalfenster:

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

Das Drehbuch:

#!/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"
Jacob Vlijm
quelle
4

Eine einfache Möglichkeit ist die Verwendung colordiff, die sich so verhält, diffaber die Ausgabe einfärbt. Dies ist sehr hilfreich zum Lesen von Unterschieden. Verwenden Sie Ihr Beispiel,

$ 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

Wobei die uOption ein einheitliches Diff ergibt. So sieht das eingefärbte Diff aus:

Bildbeschreibung hier eingeben

Installieren Sie colordiffdurch Ausführen sudo apt-get install colordiff.

edwinksl
quelle
1
Wenn Sie Farben wollen, finde ich, dass das in vim eingebaute Diff einfach zu bedienen ist, wie in der Antwort von Mr.S
thomasrutter,
2

Zusätzliche Antwort

Wenn Sie nicht wissen müssen, welche Teile der Dateien unterschiedlich sind, können Sie die Prüfsumme der Datei verwenden. Es gibt viele Möglichkeiten, dies mit md5sumoder zu tun sha256sum. Grundsätzlich gibt jeder von ihnen eine Zeichenfolge aus, zu der ein Dateiinhalt-Hash gehört. Wenn die beiden Dateien identisch sind, ist auch der Hash identisch. Dies wird häufig verwendet, wenn Sie Software herunterladen, z. B. Ubuntu-Installations-ISO-Images. Sie werden häufig zur Überprüfung der Integrität eines heruntergeladenen Inhalts verwendet.

Betrachten Sie das folgende Skript, in dem Sie zwei Dateien als Argumente angeben können. In der Datei wird angegeben, ob sie identisch sind oder nicht.

#!/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

Probelauf:

$ ./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

Ältere Antwort

Zusätzlich gibt es einen commBefehl, der zwei sortierte Dateien vergleicht und die Ausgabe in 3 Spalten liefert: Spalte 1 für Elemente, die nur in Datei 1 vorhanden sind, Spalte 2 für Elemente, die nur in Datei 2 vorhanden sind, und Spalte 3 für Elemente, die in beiden Dateien vorhanden sind.

Zum Unterdrücken einer Spalte können Sie die Schalter -1, -2 und -3 verwenden. Mit -3 werden die Zeilen angezeigt, die sich unterscheiden.

Unten sehen Sie den Screenshot des Befehls in Aktion.

Bildbeschreibung hier eingeben

Es gibt nur eine Anforderung: Die Dateien müssen sortiert sein, damit sie richtig verglichen werden können. sortBefehl kann für diesen Zweck verwendet werden. Unten sehen Sie einen weiteren Screenshot, in dem Dateien sortiert und dann verglichen werden. Zeilen, die links beginnen, gehören nur zu File_1, Zeilen, die in Spalte 2 beginnen, gehören nur zu File_2

Bildbeschreibung hier eingeben

Sergiy Kolodyazhnyy
quelle
@ DavidFoerster es ist ein bisschen schwer, auf dem Handy zu bearbeiten :) Jetzt aber
fertig
2

Installieren Sie Git und verwenden Sie

$ git diff filename1 filename2

Und Sie erhalten eine Ausgabe in schönen Farben

Git- Installation

$ apt-get update
$ apt-get install git-core
Eric Korolev
quelle
2

colcmp.sh

Vergleicht Name / Wert-Paare in 2 Dateien im Format name value\n. Schreibt das namezu, Output_filewenn es geändert wird. Benötigt bash v4 + für assoziative Arrays .

Verwendungszweck

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

Ausgabedatei

$ cat Output_File
User3 has changed

Quelle (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

Erläuterung

Aufschlüsselung des Codes und was er bedeutet, nach bestem Wissen. Ich freue mich über Änderungen und Vorschläge.

Basic File Compare

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

cmp setzt den Wert von $? wie folgt :

  • 0 = Dateien stimmen überein
  • 1 = Dateien unterscheiden sich
  • 2 = Fehler

Ich habe mich für eine case .. esac- Anweisung entschieden, um $ auszuwerten . weil der Wert von $? ändert sich nach jedem Befehl, einschließlich test ([).

Alternativ könnte ich eine Variable verwendet haben, um den Wert von $ zu halten ? :

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

Oben wird dasselbe wie in der case-Anweisung gemacht. IDK was mir besser gefällt.

Löschen Sie die Ausgabe

        echo "" > Output_File

Oben wird die Ausgabedatei gelöscht. Wenn also keine Benutzer geändert wurden, ist die Ausgabedatei leer.

Ich mache dies in den case- Anweisungen, damit die Output_file im Fehlerfall unverändert bleibt.

Kopieren Sie die Benutzerdatei in das Shell-Skript

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

Oben kopiert File_1.txt in das Ausgangsverzeichnis des aktuellen Benutzers.

Wenn der aktuelle Benutzer beispielsweise john ist, ist das oben Genannte dasselbe wie cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh

Sonderzeichen entkommen

Grundsätzlich bin ich paranoid. Ich weiß, dass diese Zeichen eine besondere Bedeutung haben oder ein externes Programm ausführen können, wenn sie in einem Skript als Teil der Variablenzuweisung ausgeführt werden:

  • `- back-tick - führt ein Programm und die Ausgabe so aus, als ob die Ausgabe Teil Ihres Skripts wäre
  • $ - Dollarzeichen - stellt normalerweise eine Variable voran
  • $ {} - ermöglicht eine komplexere Variablensubstitution
  • $ () - idk was dies tut, aber ich denke, es kann Code ausführen

Was ich nicht weiß, ist, wie viel ich nicht über Bash weiß. Ich weiß nicht, welche anderen Zeichen eine besondere Bedeutung haben könnten, aber ich möchte sie alle mit einem Backslash umgehen:

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

sed kann viel mehr als nur den Mustervergleich mit regulären Ausdrücken . Das Skriptmuster "s / (find) / (replace) /" führt speziell die Musterübereinstimmung durch.

"s / (find) / (replace) / (modifiers)"

in englischer Sprache: Zeichensetzung oder Sonderzeichen als Erfassungsgruppe 1 erfassen (\\ 1)

  • (Ersetzen) = \\\\\\ 1
    • \\\\ = Literales Zeichen (\\), dh ein Backslash
    • \\ 1 = Gruppe 1 erfassen

auf englisch: allen Sonderzeichen einen Backslash voranstellen

  • (Modifikatoren) = g
    • g = global ersetzen

auf englisch: wenn mehr als eine Übereinstimmung in derselben Zeile gefunden wird, ersetzen Sie sie alle

Kommentieren Sie das gesamte Skript aus

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

Oben wird ein regulärer Ausdruck verwendet, um jeder Zeile von ~ / .colcmp.arrays.tmp.sh ein Bash-Kommentarzeichen ( # ) voranzustellen . Ich mache das, weil ich später vorhabe, ~ / .colcmp.arrays.tmp.sh mit dem Befehl source auszuführen, und weil ich das gesamte Format von nicht genau kenne File_1.txt kenne .

Ich möchte nicht versehentlich beliebigen Code ausführen. Ich glaube nicht, dass jemand das tut.

s / (find) / (replace) /

in Englisch: Erfassen Sie jede Zeile als Erfassungsgruppe 1 (\\ 1)

  • (Ersetzen) = # \\ 1
    • # = Literales Zeichen (#), dh ein Rautezeichen oder ein Rautezeichen
    • \\ 1 = Gruppe 1 erfassen

in englischer sprache: ersetzen sie jede zeile durch ein rautenzeichen, gefolgt von der zeile, die ersetzt wurde

Benutzerwert in A1 konvertieren [User] = "value"

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

Oben ist der Kern dieses Skripts.

  • konvertiere dies: #User1 US
    • dazu: A1[User1]="US"
    • oder dies: A2[User1]="US"(für die 2. Datei)

s / (find) / (replace) /

auf Englisch:

  • Benötige aber ignoriere führende Kommentarzeichen (#)
  • Ignorieren Sie führende Leerzeichen
  • Erfassen Sie das erste Wort als Erfassungsgruppe 1 (\\ 1)
  • Benötige ein Leerzeichen (oder Tabulator oder Leerzeichen)
    • Das wird durch ein Gleichheitszeichen ersetzt, weil
    • Es ist nicht Teil einer Erfassungsgruppe, und weil
    • Das Muster (Ersetzen) setzt ein Gleichheitszeichen zwischen Erfassungsgruppe 1 und Erfassungsgruppe 2
  • Erfassen Sie den Rest der Zeile als Erfassungsgruppe 2

  • (Ersetzen) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"

    • A1 \\ [- Literalzeichen A1[zum Starten der Arrayzuweisung in einem aufgerufenen ArrayA1
    • \\ 1 = Gruppe erfassen 1 - ohne führenden Hash (#) und ohne führenden Whitespace - In diesem Fall wird Erfassungsgruppe 1 verwendet, um den Namen des Name / Wert-Paares im assoziativen Bash-Array festzulegen.
    • \\] = \ "= Literalzeichen ]="
      • ]= nahe A1[Arrayzuordnung zB User1 ]="US"
      • = = Zuweisungsoperator zB Variable = Wert
      • " = Anführungszeichen, um Leerzeichen zu erfassen ... obwohl es jetzt, wo ich darüber nachdenke, einfacher gewesen wäre, den Code über diesem Backslash alles in Backslash-Leerzeichen umzuwandeln.
    • \\ 1 = Erfassungsgruppe 2 - in diesem Fall der Wert des Name / Wert-Paares
    • "= schließender Anführungszeichenwert zum Erfassen von Leerzeichen

auf Englisch: Ersetzen Sie jede Zeile im Format #name valuedurch einen Array-Zuweisungsoperator im FormatA1[name]="value"

Ausführbar machen

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

Oben wird chmod verwendet , um die Array-Skriptdatei ausführbar zu machen.

Ich bin mir nicht sicher, ob das notwendig ist.

Assoziatives Array deklarieren (bash v4 +)

        declare -A A1

Das Großbuchstaben -A gibt an, dass die deklarierten Variablen assoziative Arrays sind .

Aus diesem Grund benötigt das Skript bash v4 oder höher.

Führen Sie unser Array-Variablenzuweisungsskript aus

        source ~/.colcmp.arrays.tmp.sh

Wir haben schon:

  • konvertierte unsere Datei von Zeilen User valuezu Zeilen von A1[User]="value",
  • machte es ausführbar (vielleicht), und
  • deklarierte A1 als assoziatives Array ...

Oben haben wir beziehen das Skript es in dem aktuell Shell ausgeführt werden . Wir tun dies, um die vom Skript gesetzten Variablenwerte beizubehalten. Wenn Sie das Skript direkt ausführen, wird eine neue Shell erstellt, und die Variablenwerte gehen verloren, wenn die neue Shell beendet wird.

Dies sollte eine Funktion sein

        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

Wir machen dasselbe für $ 1 und A1 wie für $ 2 und A2 . Es sollte wirklich eine Funktion sein. Ich denke, an diesem Punkt ist dieses Skript verwirrend genug und es funktioniert, also werde ich es nicht reparieren.

Entfernte Benutzer erkennen

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

Oben werden assoziative Array-Schlüssel durchlaufen

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

Oben wird die Variablensubstitution verwendet, um den Unterschied zwischen einem nicht festgelegten Wert und einer Variablen zu ermitteln, die explizit auf eine Zeichenfolge der Länge Null festgelegt wurde.

Anscheinend gibt es viele Möglichkeiten, um festzustellen, ob eine Variable festgelegt wurde . Ich habe den mit den meisten Stimmen gewählt.

                echo "$i has changed" > Output_File

Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt

Erkennen Sie hinzugefügte oder geänderte Benutzer

        USERSWHODIDNOTCHANGE=

Oben wird eine Variable gelöscht, damit wir die Benutzer verfolgen können, die sich nicht geändert haben.

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

Oben werden assoziative Array-Schlüssel durchlaufen

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

Oben wird die Variablensubstitution verwendet, um festzustellen, ob eine Variable festgelegt wurde .

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

Da $ i der Array-Schlüssel (Benutzername) ist, sollte $ A2 [$ i] den Wert zurückgeben, der dem aktuellen Benutzer aus File_2.txt zugeordnet ist .

Wenn zum Beispiel $ i ist User1 , die oben lautet wie $ {A2 [User1]}

                echo "$i has changed" > Output_File

Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt

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

Da $ i der Array-Schlüssel (Benutzername) ist, sollte $ A1 [$ i] den dem aktuellen Benutzer zugeordneten Wert aus File_1.txt und $ A2 [$ i] den Wert aus File_2.txt zurückgeben .

Oben werden die zugehörigen Werte für Benutzer $ i aus beiden Dateien verglichen .

                echo "$i has changed" > Output_File

Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt

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

Oben wird eine durch Kommas getrennte Liste von Benutzern erstellt, die sich nicht geändert haben. Beachten Sie, dass die Liste keine Leerzeichen enthält. Andernfalls muss der nächste Scheck in Anführungszeichen gesetzt werden.

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

Oben wird der Wert von $ USERSWHODIDNOTCHANGE gemeldet, jedoch nur, wenn $ USERSWHODIDNOTCHANGE einen Wert enthält . So wie dies geschrieben ist, darf $ USERSWHODIDNOTCHANGE keine Leerzeichen enthalten. Wenn Leerzeichen erforderlich sind, könnte dies wie folgt geändert werden:

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