Hvordan finder jeg to filer, der matcher data i shell-script, og duplikerer datalager i en anden fil i 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
Jeg skrev kode, men den fungerede ikke. Hvordan skriver jeg den?
Kommentarer
Svar
For bare at teste om to filer er de samme, brug 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
flag til cmp
vil gøre hjælpeprogrammet til “stille”. Afslutningsstatus for cmp
er nul, når man sammenligner to identiske filer. Dette bruges i koden ovenfor til at udskrive en besked om, hvorvidt de to filer er identiske eller ej.
Hvis dine to inputfiler indeholder en liste over stienavne af filer som du vil sammenligne, og brug derefter en dobbelt loop som sådan:
Her produceres resultatet på både terminalen og i filen file-comparison.out
.
Det antages, at intet stinavn i de to inputfiler indeholder nogen indlejrede nye linjer.
Koden læser først alle stienavne fra en af filerne ind i en matrix, files1
ved hjælp af mapfile
. Jeg gør dette for at undgå at skulle læse den fil mere end én gang, da vi bliver nødt til at gennemgå alle disse vejnavne for hvert stinavn i den anden fil. Du vil bemærke, at i stedet for at læse fra $filelist1
i den indre sløjfe, gentager jeg bare navnene i files1
array.
Kommentarer
- jeg har brug for total progam i bash shell
- @santhoshreddy Se opdateret svar.
Svar
Den nemmeste måde er at bruge kommandoen diff
.
eksempel:
lad os antage, at den første fil er file1.txt
og han indeholder:
I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.`
og den anden fil 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.
så kan vi bruge diff til automatisk at vise for os, hvilke linjer der er forskellige mellem de to filer med denne kommando:
diff file1.txt file2.txt
og output vil være:
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.
Lad os se på, hvad denne output betyder. Den vigtige ting at huske er, at når diff beskriver disse forskelle for dig, gør det det i en receptpligtig sammenhæng: det fortæller dig, hvordan du ændrer den første fil, så den matcher den anden fil. Den første linje i diff-output vil indeholde:
- linjenumre svarende til den første fil,
- et bogstav (a for tilføj, c for ændring eller d for sletning )
- linjenumre svarende til den anden fil.
I vores output ovenfor “2,4c2,4 “ betyder:” Linjer 2 til 4 i den første fil skal ændres for at matche linjer 2 til 4 i den anden fil. ” Derefter fortæller det os, hvad disse linjer er i hver fil:
- Linjer forud for en < er linjer fra den første fil;
- linjer forud for> er linjer fra den anden fil.
- De tre bindestreger (“—“) adskiller blot linjerne i fil 1 og fil 2.
Svar
Her er et rent bash shell-script til sammenligning af filer:
#!/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
producerer:
$ ./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.
Kommentarerne til specifikke kommandoer kan fjernes for at afslutte ved den første forskel set, og hvis du ønsker at se hver linje, der læses.
Se side på http://www.linuxjournal.com/content/reading-multiple-files-bash for detaljer om filbeskrivere som “& 3”.
Bedste ønsker … skål, drl
Kommentarer
-
head
er et eksternt værktøj, og hvad er$HOME/bin/context
? Og hvad betyder kommentarerne øverst? - Head viser input. Det spiller ikke fra hinanden i forskellen. Som med nogle andre elementer er ” kontekst ” lokal for at vise miljøkonteksten. Ved at inkludere det behøver vi ikke ‘ at diskutere, om versioner af OSer og anvendelsesmuligheder er forskellige.
- Der manglede en eksport, tak for at du bemærkede det.
- Jeg forstår stadig ikke ‘ ikke forstå kommentaren.Hvad ‘ er en ” ekstern bruger “, og hvorfor vil du indstille sti til et script, der er rent
bash
? - Vi skriver kode til vores butik, så stiindstillingerne kan variere for eksterne brugere. Vi tilføjer, at hvis det synes nødvendigt at udelade vores indstillinger. Dette er en skabelon, der er modificeret til at vise oplysningerne om det miljø, hvor koden blev udført. Hvis det ville blive omdannet til en produktionskode, f.eks. For klienter, i stedet for en demo-kode, vil vi ‘ d være sikre på, at ingen af vores lokale stier bruges. for context er designet således, at hvis filen ikke findes, vil der ikke ske noget, ikke engang en fejl, men ingen versioner vil blive anført.
diff
kommando?