GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Diff -r nur für bestimmte Dateitypen?

Gibt es eine Möglichkeit, einen rekursiven Vergleich zweier Verzeichnisse durchzuführen, aber nur Dateien (an ihren jeweiligen Stellen) zu vergleichen, die einem bestimmten Dateinamen oder Dateityp-Prädikat entsprechen?

Z.B. Ich möchte etwas tun wie

diff -r dir-a dir-b -filenames *.java, ivy.xml, build.xml

… oder noch besser:

diff -r dir-a dir-b -filetype text

Natürlich ist es nicht zwingend erforderlich, diff zu verwenden wie ich eine Beschwörung mit find annehme und -exec diff könnte auch den Zweck erfüllen (ich weiß nur nicht, wie ich im letzteren Fall die komplementären Dateipfade generieren soll).

Akzeptierte Antwort:

Shellscript differ-r

Dieses Shellscript kann einen rekursiven Vergleich zweier Verzeichnisse durchführen, aber nur Dateien (an ihren jeweiligen Stellen) vergleichen, die einem bestimmten Dateinamen oder Dateitypmuster entsprechen.

#!/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 {} +

Demo

Dateien:

$ 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

Verwendung:

$ ./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"

Ausführen von differ-r :

Der durchgeführte diff Befehlszeilen werden mit grünem Text gedruckt und die Ausgabe, wenn es keine Übereinstimmung gibt, wird mit Standardtext gedruckt (weiß auf schwarz im folgenden Screenshot).

$ ./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 mit Filter

Wenn Sie keine Ausgabe erhalten müssen, die den Unterschied beschreibt, wissen Sie nur, welche Dateien unterschiedlich sind oder fehlen (damit rsync kopieren möchten), können Sie die folgende Befehlszeile verwenden.

rsync --filter="+ <pattern>" --filter="+ */" --filter="- *"--filter="- */"  -avcn <source directory>/ <target directory>

Demo

$ 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)
[email protected] /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)

Wenn Sie eine saubere Ausgabe ohne Kommentarzeilen und ohne Verzeichnisse wünschen, können Sie grep verwenden die Ausgabe so,

$ pattern="*.doc"; rsync --filter="+ $pattern" --filter="+ */" --filter="- *"  -avcn 1/ 2 | grep "${pattern/\*/.\*}"
sub/hello.doc
sub/only-one.doc

Shellscript rsync-diff

Dieser Einzeiler kann zum Kernbefehl eines Shellscripts rsync-diff gemacht werden .

#!/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)$'

Linux
  1. Existiert ein Liner zum Überprüfen der Datei?

  2. Rsync Zwei Dateitypen in einem Befehl?

  3. Wozu dient die .la-Datei von libtool?

  4. Wie unterscheiden Sie ein Verzeichnis nur für Dateien eines bestimmten Typs?

  5. diff, um nur die Dateinamen auszugeben

ls-Befehl in Linux zum Auflisten von Dateien

Exa – Ein moderner Ersatz für den Befehl ls

Messen Sie den Speicherplatz bestimmter Dateitypen insgesamt

Wie kann ich Dateien finden, die nur bestimmte Rechte für den Besitzer haben?

Machen Sie die Datei unter Linux auch für root schreibgeschützt

Ist dieser Studienführer in Bezug auf Befehle zum Bestimmen von Dateitypen falsch?