Shellscript differ-r
Ce shellscript peut effectuer un diff récursif de deux répertoires mais comparer uniquement (à leurs emplacements respectifs) les fichiers qui correspondent à un nom de fichier ou un modèle de type de fichier spécifique.
#!/bin/bash
greenvid="\0033[32m"
resetvid="\0033[0m"
if [ $# -ne 3 ]
then
echo "Usage: compare files in two directories including subdirectories"
echo " $0 <source-dir> <target-dir> <pattern>"
echo "Example: $0 subdir-1 subdir-2 \"*.txt\""
exit
fi
cmd='for pathname do
greenvid="\0033[32m"
resetvid="\0033[0m"
echo -e "${greenvid}diff \"$pathname\" \"${pathname/'\"$1\"'/'\"$2\"'}\"${resetvid}"
diff "$pathname" "${pathname/'\"$1\"'/'\"$2\"'}"
done'
#echo "$cmd"
find "$1" -type f -name "$3" -exec bash -c "$cmd" bash {} +
Démo
Des dossiers:
$ find -type f
./1/ett.txt
./1/two.doc
./1/t r e.txt
./1/sub/only-one.doc
./1/sub/hello.doc
./1/sub/hejsan.doc
./differ-r2
./differ-r1
./differ-r
./2/ett.txt
./2/two.doc
./2/t r e.txt
./2/sub/hello.doc
./2/sub/hejsan.doc
Usage:
$ ./differ-r
Usage: compare files in two directories including subdirectories
./differ-r <source-dir> <target-dir> <pattern>
Example: ./differ-r subdir-1 subdir-2 "*.txt"
Courir differ-r
:
Les diff
lignes de commande exécutées sont imprimées avec du texte vert et la sortie, lorsqu'il n'y a pas de correspondance, est imprimée avec le texte par défaut (blanc sur noir dans la capture d'écran suivante).
$ ./differ-r 1 2 "*.doc"
diff "1/two.doc" "2/two.doc"
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"
$ ./differ-r 1 2 "*.txt"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
$
$ ./differ-r 1 2 "*"
diff "1/ett.txt" "2/ett.txt"
2c2
< stabben
---
> farsan
diff "1/two.doc" "2/two.doc"
diff "1/t r e.txt" "2/t r e.txt"
1c1
< t r e
---
> 3
diff "1/sub/only-one.doc" "2/sub/only-one.doc"
diff: 2/sub/only-one.doc: No such file or directory
diff "1/sub/hello.doc" "2/sub/hello.doc"
2d1
< world
diff "1/sub/hejsan.doc" "2/sub/hejsan.doc"
$ ./differ-r 2 1 "*"
diff "2/ett.txt" "1/ett.txt"
2c2
< farsan
---
> stabben
diff "2/two.doc" "1/two.doc"
diff "2/t r e.txt" "1/t r e.txt"
1c1
< 3
---
> t r e
diff "2/sub/hello.doc" "1/sub/hello.doc"
1a2
> world
diff "2/sub/hejsan.doc" "1/sub/hejsan.doc"
rsync
avec filtre
Si vous n'avez pas besoin d'obtenir de sortie décrivant la différence, sachez uniquement quels fichiers sont différents ou manquants (de sorte que vous rsync
souhaitez les copier), vous pouvez utiliser la ligne de commande suivante.
rsync --filter="+ <pattern>" --filter="+ */" --filter="- *"--filter="- */" -avcn <source directory>/ <target directory>
Démo
$ rsync --filter="+ *.doc" --filter="+ */" --filter="- *" -avcn 1/ 2
sending incremental file list
./
sub/
sub/hello.doc
sub/only-one.doc
sent 276 bytes received 35 bytes 622.00 bytes/sec
total size is 40 speedup is 0.13 (DRY RUN)
sent 360 bytes received 41 bytes 802.00 bytes/sec
total size is 61 speedup is 0.15 (DRY RUN)
olle@bionic64 /media/multimed-2/test/test0/temp $ rsync --filter="+ *.txt" --filter="+ */" --filter="- *" -avcn 1/ 2
sending incremental file list
./
ett.txt
t r e.txt
sub/
sent 184 bytes received 29 bytes 426.00 bytes/sec
total size is 21 speedup is 0.10 (DRY RUN)
Si vous voulez une sortie propre sans lignes de commentaires et sans répertoires, vous pouvez grep
la sortie comme ça,
$ pattern="*.doc"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *" -avcn 1/ 2 | grep "${pattern/\*/.\*}"
sub/hello.doc
sub/only-one.doc
Shellscript rsync-diff
Ce one-liner peut être transformé en commande de base d'un script shell rsync-diff
.
#!/bin/bash
LANG=C
if [ $# -ne 3 ]
then
echo "Usage: compare files in two directories including subdirectories"
echo " $0 <source-dir> <target-dir> <pattern>"
echo "Example: $0 subdir-1 subdir-2 \"*.txt\""
exit
fi
pattern="$3"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *" \
-avcn "$1"/ "$2" | grep "${pattern//\*/.\*}" | grep -v \
-e '/$' \
-e '^sending incremental file list$' \
-e '^sent.*received.*sec$' \
-e '^total size is.*speedup.*(DRY RUN)$'