Cum se găsesc două fișiere care se potrivesc cu datele în scriptul shell și cu un duplicat al stocării datelor într-un alt fișier din 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
Am scris cod, dar nu a funcționat. Cum să-l scriu?
Comentarii
Răspuns
Pentru a testa doar dacă două fișierele sunt aceleași, utilizați 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
-s
semnalizare la cmp
va face utilitarul „silențios”. Starea de ieșire a cmp
va fi zero atunci când se compară două fișiere identice. Aceasta este utilizată în codul de mai sus pentru a imprima un mesaj despre dacă cele două fișiere sunt sau nu identice.
Dacă cele două fișiere de intrare conține o listă de căi a fișierelor pe care doriți să o comparați, apoi utilizați o buclă dublă astfel:
Aici, rezultatul este produs atât pe terminal, cât și în fișierul file-comparison.out
.
Se presupune că niciun nume de cale din cele două fișiere de intrare nu conține linii noi încorporate.
Codul citește mai întâi toate căile de acces dintr-unul dintre fișiere într-o matrice, files1
, folosind mapfile
. Fac asta pentru a evita să citesc fișierul respectiv de mai multe ori, întrucât va trebui să parcurgem toate acele nume de cale pentru fiecare cale de acces din celălalt fișier. Veți observa că, în loc să citesc din $filelist1
în bucla interioară, iterez doar numele din matricea files1
.
Comentarii
- Am nevoie de progam total în shell bash
- @santhoshreddy Vezi răspunsul actualizat.
Răspuns
Cel mai simplu mod este să folosiți comanda diff
.
exemplu:
să presupunem că primul fișier este file1.txt
și conține:
I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.`
și al doilea fișier 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.
atunci putem folosi diff pentru a afișa automat pentru noi ce linii diferă între cele două fișiere cu această comandă:
diff file1.txt file2.txt
iar ieșirea va fi:
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.
Să aruncăm o privire la ceea ce înseamnă această ieșire. Important este să vă amintiți că atunci când dif vă descrie aceste diferențe, o face într-un context prescriptiv: vă spune cum să schimbați primul fișier pentru a face să se potrivească cu al doilea fișier. Prima linie a ieșirii dif va conține:
- numere de linie corespunzătoare primului fișier,
- o literă (a pentru adăugare, c pentru modificare sau d pentru ștergere )
- numere de linie corespunzătoare celui de-al doilea fișier.
În rezultatul de mai sus, „2,4c2,4 „ înseamnă:” Linii 2 prin 4 din primul fișier trebuie modificat pentru a se potrivi liniilor 2 prin 4 în al doilea fișier. ” Apoi ne spune care sunt acele linii din fiecare fișier:
- Liniile precedate de un < sunt linii din primul fișier;
- liniile precedate de> sunt linii din al doilea fișier.
- Cele trei liniuțe („—”) separă doar liniile fișierului 1 și ale fișierului 2.
Răspuns
Iată un script bash shell pentru a compara fișiere:
#!/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
producând:
$ ./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.
Comentariile la comenzi specifice pot fi eliminate pentru a ieși la prima diferență văzută și dacă doriți să vedeți fiecare linie citită.
Consultați pagina la http://www.linuxjournal.com/content/reading-multiple-files-bash pentru detalii despre descriptorii de fișiere, cum ar fi „& 3”.
Cele mai bune urări … drl
Comentarii
-
head
este un utilitar extern și ce este$HOME/bin/context
? Și ce înseamnă comentariile în partea de sus? - Head afișează intrarea. Nu se joacă separat în diferențiere. Ca și în cazul altor elemente, ” context ” este local pentru a arăta contextul mediului. Prin includerea acestui fapt, nu trebuie ‘ să fim nevoiți să discutăm dacă versiunile de sisteme de operare și utilități diferă.
- A lipsit un export, mulțumim că ați observat acest lucru.
- Încă nu ‘ nu înțeleg comentariul.Ce ‘ este un ” utilizator extern ” și de ce doriți să setați cale pentru un script care este pur
bash
? - Scriem cod pentru magazinul nostru, astfel încât setările căii pot diferi pentru utilizatorii externi. Adăugăm că, dacă pare necesar să omitem setările noastre. Acesta este un șablon care este modificat pentru a afișa informațiile despre mediul în care a fost executat codul. Dacă s-ar transforma într-un cod de producție, să spunem pentru clienți, în loc de cod demo, ‘ dorim să fim siguri că niciuna dintre căile noastre locale nu este folosită. pentru context este conceput astfel încât, dacă fișierul respectiv nu este găsit, nu se va întâmpla nimic, nici măcar o eroare, dar nu vor fi listate versiuni.
diff
comandă?