Jak najít dva soubory shodných dat ve skriptu prostředí a duplikovat úložiště dat v jiném souboru ve skořápce?
#!/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
Napsal jsem kód, ale nefungoval. Jak jej napsat?
Komentáře
Odpověď
Chcete-li jen otestovat, zda jsou dva soubory jsou stejné, použijte 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
příznak cmp
způsobí, že bude obslužný program „tichý“. Stav ukončení cmp
bude při porovnání dvou identických souborů nulový. Toto se používá v kódu výše k vytištění zprávy o tom, zda jsou tyto dva soubory identické nebo ne.
Pokud vaše dva vstupní soubory obsahuje seznam názvů cest souborů které chcete porovnat, použijte dvojitou smyčku takto:
Zde se výsledek vytvoří jak na terminálu, tak v souboru file-comparison.out
.
Předpokládá se, že žádný název cesty ve dvou vstupních souborech neobsahuje žádné vložené nové řádky.
Kód nejprve přečte všechny názvy cest z jednoho ze souborů do pole, files1
pomocí mapfile
. Dělám to, abych nemusel tento soubor číst vícekrát, protože budeme muset projít všechny tyto názvy cest pro každou cestu v druhém souboru. Všimnete si, že namísto čtení z $filelist1
ve vnitřní smyčce pouze opakuji názvy v poli files1
.
Komentáře
- Potřebuji celkový program v prostředí bash shell
- @santhoshreddy Zobrazit aktualizovanou odpověď.
Odpověď
Nejjednodušší způsob je použít příkaz diff
.
příklad:
předpokládejme, že první soubor je file1.txt
a on obsahuje:
I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.`
a druhý soubor 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.
pak můžeme pomocí diff automaticky zobrazit, které řádky se liší mezi dvěma soubory pomocí tohoto příkazu:
diff file1.txt file2.txt
a výstup bude:
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.
Pojďme se podívat, co tento výstup znamená. Důležité je zapamatovat si, že když vám diff popisuje tyto rozdíly, dělá to v normativním kontextu: říká vám, jak změnit první soubor tak, aby odpovídal druhému souboru. První řádek výstupu rozdílu bude obsahovat:
- čísla řádků odpovídající prvnímu souboru,
- písmeno (a pro přidání, c pro změnu nebo d pro odstranění )
- čísla řádků odpovídající druhému souboru.
V našem výstupu výše „2,4c2,4 „ znamená:“ Řádky 2 až 4 v prvním souboru je třeba změnit tak, aby odpovídaly řádkům 2 až 4 ve druhém souboru. “ Potom nám řekne, jaké jsou tyto řádky v každém souboru:
- Řádky, kterým předchází <, jsou řádky z prvního souboru;
- řádky, kterým předchází>, jsou řádky z druhého souboru.
- Tři pomlčky („—“) pouze oddělují řádky souboru 1 a souboru 2.
Odpověď
Zde je čistý skript bash shellu pro porovnání souborů:
#!/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
produkovat:
$ ./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.
Komentáře k konkrétní příkazy lze odebrat, aby se ukončily při prvním pozorovaném rozdílu a pokud si přejete vidět každý přečtený řádek.
Viz stránka na http://www.linuxjournal.com/content/reading-multiple-files-bash pro podrobnosti o deskriptorech souborů, například „& 3“.
S pozdravem, na zdraví, drl
Komentáře
-
head
je externí nástroj a co je$HOME/bin/context
? A co znamenají komentáře nahoře? - Head zobrazuje vstup. Nehraje to odděleně. Stejně jako u některých dalších položek je “ kontext “ místní, aby zobrazoval kontext prostředí. Zahrnutím toho nemusíme ‚ diskutovat o tom, zda se liší verze operačních systémů a nástrojů.
- Chyběl export, děkujeme, že jste si toho všimli.
- Stále nerozumím komentáři ‚.Co ‚ je “ externí uživatel “ a proč byste chtěli nastavit cesta k čistému skriptu
bash
? - Píšeme kód pro náš obchod, takže nastavení cesty se může u externích uživatelů lišit. Dodáváme, že pokud se bude zdát nutné naše nastavení vynechat. Toto je šablona, která je upravena tak, aby zobrazovala informace o prostředí, ve kterém byl kód spuštěn. Pokud by byl transformován do produkčního kódu, řekněme pro klienty, místo demo kódu bychom chtěli mít ‚ jistotu, že není použita žádná z našich místních cest. pro kontext je navržen tak, že pokud tento soubor nebude nalezen, nic se nestane, ani chyba, ale nebudou uvedeny žádné verze.
diff
příkaz?