Hur hittar jag två filer som matchar data i skalskript och duplicerar datalager i en annan fil i skal?
#!/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
Jag skrev kod men den fungerade inte. Hur skriver jag den?
Kommentarer
Svar
För att bara testa om två filerna är desamma, använd 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
flagga till cmp
gör verktyget ”tyst”. Utgångsstatus för cmp
blir noll när man jämför två identiska filer. Detta används i koden ovan för att skriva ut ett meddelande om huruvida de två filerna är identiska eller inte.
Om dina två inmatningsfiler innehåller en lista med sökvägar med filer som du vill jämföra, använd sedan en dubbel slinga så:
Här produceras resultatet på både terminalen och i filen file-comparison.out
.
Det antas att inget sökvägen i de två inmatningsfilerna innehåller några inbäddade nya rader.
Koden läser först alla sökvägar från en av filerna i en matris, files1
med mapfile
. Jag gör detta för att undvika att behöva läsa den filen mer än en gång, eftersom vi måste gå igenom alla de sökvägar för varje sökväg i den andra filen. Du kommer att märka att istället för att läsa från $filelist1
i den inre slingan, itererar jag bara över namnen i files1
-matrisen.
Kommentarer
- jag behöver totalt program i bash-skal
- @santhoshreddy Se uppdaterat svar.
Svar
Det enklaste sättet är att använda kommandot diff
.
exempel:
låt oss anta att den första filen är file1.txt
och han innehåller:
I need to buy apples. I need to run the laundry. I need to wash the dog. I need to get the car detailed.`
och den andra filen 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.
då kan vi använda diff för att automatiskt visa för oss vilka rader som skiljer sig mellan de två filerna med det här kommandot:
diff file1.txt file2.txt
och utgången blir:
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.
Låt oss ta en titt på vad den här utgången betyder. Det viktiga att komma ihåg är att när diff beskriver dessa skillnader för dig, gör det det i ett receptbelagt sammanhang: det berättar hur du ändrar den första filen så att den matchar den andra filen. Den första raden i diff-utgången kommer att innehålla:
- radnummer som motsvarar den första filen,
- en bokstav (a för add, c för ändring eller d för radering )
- radnummer som motsvarar den andra filen.
I vår utdata ovan ”2,4c2,4 ” betyder:” Linjer 2 till 4 i den första filen måste ändras för att matcha rader 2 till 4 i den andra filen. ” Den berättar sedan vad dessa rader är i varje fil:
- Rader föregångna av en < är rader från den första filen;
- rader som föregås av> är rader från den andra filen.
- De tre streckarna (”—”) separerar bara raderna för fil 1 och fil 2.
Svar
Här är en ren bash shell-skript för att jämföra 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
producerar:
$ ./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.
Kommentarerna till specifika kommandon kan tas bort för att avsluta vid den första skillnaden som visas, och om du vill se varje rad som läses.
Se sidan på http://www.linuxjournal.com/content/reading-multiple-files-bash för information om filbeskrivare som ”& 3”.
Bästa hälsningar … skål, drl
Kommentarer
-
head
är ett externt verktyg, och vad är$HOME/bin/context
? Och vad betyder kommentarerna högst upp? - Head visar inmatningen. Det spelar inte ifrån varandra i skillnaden. Som med andra objekt är ” kontext ” lokalt för att visa miljökontexten. Genom att inkludera det behöver vi inte ’ diskutera om versioner av operativsystem och användningsområden skiljer sig åt.
- Det saknades en export, tack för att du märkte det.
- Jag förstår fortfarande inte ’ inte kommentaren.Vad ’ är en ” extern användare ”, och varför vill du ställa in sökväg för ett skript som är rent
bash
? - Vi skriver kod för vår butik, så sökinställningarna kan skilja sig för externa användare. Vi tillägger att om det verkar nödvändigt att utelämna våra inställningar. Det här är en mall som modifieras för att visa information om den miljö där koden kördes. Om den skulle förvandlas till en produktionskod, säg för klienter, istället för en demokod, vill vi ’ vara säker på att ingen av våra lokala sökvägar används. för sammanhang är utformat så att om filen inte hittas kommer inget att hända, inte ens ett fel, men inga versioner skulle listas.
diff
kommando?