Wie finde ich zwei Dateien, die mit Daten im Shell-Skript übereinstimmen, und dupliziere den Datenspeicher in einer anderen Datei in der Shell?
#!/bin/bash file1="/home/vekomy/santhosh/bigfiles.txt" file2="/home/vekomy/santhosh/bigfile2.txt" while read -r $file1; do while read -r $file2 ;do if [$file1==$file2] ; then echo "two files are same" else echo "two files content different" fi done done
Ich habe Code geschrieben, aber er hat nicht funktioniert. Wie schreibe ich ihn?
Kommentare
- Haben Sie versucht, ihn zu verwenden?
diff
Befehl?
Antwort
Um nur zu testen, ob zwei Dateien sind identisch. Verwenden Sie cmp -s
:
#!/bin/bash file1="/home/vekomy/santhosh/bigfiles.txt" file2="/home/vekomy/santhosh/bigfile2.txt" if cmp -s "$file1" "$file2"; then printf "The file "%s" is the same as "%s"\n" "$file1" "$file2" else printf "The file "%s" is different from "%s"\n" "$file1" "$file2" fi
Die -s
Flag auf cmp
macht das Dienstprogramm „stumm“. Der Exit-Status von cmp
ist Null, wenn zwei identische Dateien verglichen werden. Dies wird im obigen Code verwendet, um eine Nachricht darüber auszudrucken, ob die beiden Dateien identisch sind oder nicht.
Wenn Ihre beiden Eingabedateien eine Liste von Pfadnamen von Dateien enthalten die Sie vergleichen möchten, verwenden Sie dann eine Doppelschleife wie folgt:
Hier wird das Ergebnis sowohl auf dem Terminal als auch in der Datei file-comparison.out
.
Der Code liest zuerst alle Pfadnamen aus einer der Dateien in ein Array, files1
mit mapfile
. Ich mache das, um zu vermeiden, dass ich diese Datei mehr als einmal lesen muss, da wir alle diese Pfadnamen für jeden Pfadnamen in der anderen Datei durchgehen müssen. Sie werden feststellen, dass ich nicht aus $filelist1
in der inneren Schleife lese, sondern nur die Namen im Array files1
durchlaufe. P. >
Kommentare
- Ich benötige ein Gesamtprogramm in der Bash-Shell.
- @santhoshreddy Siehe aktualisierte Antwort.
Antwort
Am einfachsten ist es, den Befehl diff
zu verwenden.
Beispiel:
Nehmen wir an, die erste Datei ist file1.txt
und er enthält:
I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.`
und die zweite Datei file2.txt
I need to buy apples. I need to do the laundry. I need to wash the car. I need to get the dog detailed.
dann können wir diff verwenden, um automatisch anzuzeigen, welche Zeilen sich mit diesem Befehl zwischen den beiden Dateien unterscheiden:
diff file1.txt file2.txt
und die Ausgabe lautet:
2,4c2,4 < I need to run the laundry. < I need to wash the dog. < I need to get the car detailed. --- > I need to do the laundry > I need to wash the car. > I need to get the dog detailed.
Schauen wir uns an, was diese Ausgabe bedeutet. Das Wichtigste, an das Sie sich erinnern sollten, ist, dass diff, wenn es Ihnen diese Unterschiede beschreibt, dies in einem vorgeschriebenen Kontext tut: Es sagt Ihnen, wie Sie die erste Datei ändern müssen, damit sie mit der zweiten Datei übereinstimmt. Die erste Zeile der Diff-Ausgabe enthält:
- Zeilennummern, die der ersten Datei entsprechen,
- einen Buchstaben (a zum Hinzufügen, c zum Ändern oder d zum Löschen )
- Zeilennummern, die der zweiten Datei entsprechen.
In unserer obigen Ausgabe „2,4c2,4 „ bedeutet:“ Zeilen 2 bis 4 in der ersten Datei muss geändert werden, um mit den Zeilen 2 bis 4 in der zweiten Datei. “ Anschließend erfahren wir, welche Zeilen in jeder Datei enthalten sind:
- Zeilen, denen ein < vorangestellt ist, sind Zeilen aus der ersten Datei;
- Zeilen mit vorangestelltem> sind Zeilen aus der zweiten Datei.
- Die drei Bindestriche („—„) trennen lediglich die Zeilen von Datei 1 und Datei 2.
Antwort
Hier ist eine reine Bash-Shell-Skript zum Vergleichen von Dateien:
#!/usr/bin/env bash # @(#) s1 Demonstrate rudimentary diff using shell only. # Infrastructure details, environment, debug commands for forum posts. # Uncomment export command to run as external user: not context, pass-fail. # export PATH="/usr/local/bin:/usr/bin:/bin" set +o nounset LC_ALL=C ; LANG=C ; export LC_ALL LANG pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; } db() { : ; } C=$HOME/bin/context && [ -f "$C" ] && $C set -o nounset FILE1=${1-data1} shift FILE2=${1-data2} # Display samples of data files. pl " Data files:" head "$FILE1" "$FILE2" # Set file descriptors. exec 3<"$FILE1" exec 4<"$FILE2" # Code based on: # http://www.linuxjournal.com/content/reading-multiple-files-bash # Section 2, solution. pl " Results:" eof1=0 eof2=0 count1=0 count2=0 while [[ $eof1 -eq 0 || $eof2 -eq 0 ]] do if read a <&3; then let count1++ # printf "%s, line %d: %s\n" $FILE1 $count1 "$a" else eof1=1 fi if read b <&4; then let count2++ # printf "%s, line %d: %s\n" $FILE2 $count2 "$b" else eof2=1 fi if [ "$a" != "$b" ] then echo " File $FILE1 and $FILE2 differ at lines $count1, $count2:" pe "$a" pe "$b" # exit 1 fi done exit 0
Erstellt:
$ ./s1 Environment: LC_ALL = C, LANG = C (Versions displayed with local utility "version") OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64 Distribution : Debian 8.9 (jessie) bash GNU bash 4.3.30 ----- Data files: ==> data1 <== I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed. ==> data2 <== I need to buy apples. I need to do the laundry. I need to wash the car. I need to get the dog detailed. ----- Results: File data1 and data2 differ at lines 2, 2: I need to run the laundry. I need to do the laundry. File data1 and data2 differ at lines 3, 3: I need to wash the dog. I need to wash the car. File data1 and data2 differ at lines 4, 4: I need to get the car detailed. I need to get the dog detailed.
Die Kommentare zu Bestimmte Befehle können entfernt werden, um beim ersten Unterschied zu beenden und wenn Sie jede gelesene Zeile sehen möchten.
Siehe Seite unter http://www.linuxjournal.com/content/reading-multiple-files-bash für Details zu Dateideskriptoren wie „& 3“.
Beste Wünsche … Prost, drl
Kommentare
-
head
ist ein externes Dienstprogramm und was ist$HOME/bin/context
? Und was bedeuten die Kommentare oben? - Head zeigt die Eingabe an. Es spielt bei der Differenzierung nicht auseinander. Wie bei einigen anderen Elementen ist " Kontext " lokal, um den Umgebungskontext anzuzeigen. Indem wir dies einbeziehen, müssen wir ' nicht diskutieren, ob sich Versionen von Betriebssystemen und Dienstprogrammen unterscheiden.
- Es fehlte ein Export, danke, dass Sie dies bemerkt haben.
- Ich verstehe den Kommentar immer noch nicht '.Was ' ist ein " externer Benutzer " und warum sollten Sie das festlegen? Pfad für ein Skript, das rein ist
bash
? - Wir schreiben Code für unseren Shop, sodass die Pfadeinstellungen für externe Benutzer unterschiedlich sein können. Wir fügen dies hinzu, wenn es notwendig erscheint, unsere Einstellungen wegzulassen. Dies ist eine Vorlage, die geändert wird, um Informationen zu der Umgebung anzuzeigen, in der der Code ausgeführt wurde. Wenn es beispielsweise für Clients anstelle eines Demo-Codes in einen Produktionscode umgewandelt werden soll, möchten wir ' sicherstellen, dass keiner unserer lokalen Pfade verwendet wird. Die Befehlszeile Denn der Kontext ist so konzipiert, dass, wenn diese Datei nicht gefunden wird, nichts passiert, nicht einmal ein Fehler, aber keine Versionen aufgelistet werden.