Wie unterscheidet man ein Verzeichnis nur für Dateien eines bestimmten Typs?

86

Ich habe eine Frage zum Befehl diff, wenn ich ein rekursives Verzeichnis diff möchte, aber nur für einen bestimmten Dateityp. Wie geht das?

Ich habe versucht, die Ausschlussoption zu verwenden, kann aber nur ein Muster verwenden:

$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml

mit dem Befehl , den ich nur xml Dateityp, obwohl ausschließen kann , gibt es Dateien in dem Ordner Bildtyp ( png, gif, jpg), txt, phpusw.

wie man nur bestimmte Dateitypen unterscheidet.

de_3
quelle
1
stackoverflow.com/q/10131908/2707864
sancho.s ReinstateMonicaCellio
Versuchen Sie also, Dateien eines bestimmten Typs zu unterscheiden oder diese Dateien vom Unterschied auszuschließen? Die Frage korreliert nicht mit der Beschreibung ..
def

Antworten:

97

Sie können -xmehr als einmal angeben .

diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2

Aus dem Abschnitt Verzeichnisse vergleichen von info diff(auf meinem System muss ich Folgendes tun info -f /usr/share/info/diff.info.gz):

Verwenden Sie die Option '-x PATTERN' oder '--exclude = PATTERN', um einige Dateien beim Vergleichen von Verzeichnissen zu ignorieren. Diese Option ignoriert alle Dateien oder Unterverzeichnisse, deren Basisnamen mit dem Shell-Muster PATTERN übereinstimmen. Anders als in der Shell entspricht ein Punkt am Anfang der Basis eines Dateinamens einem Platzhalter am Anfang eines Musters. Sie sollten PATTERN in Anführungszeichen setzen, damit die Shell es nicht erweitert. Beispielsweise ignoriert die Option -x '*. [Ao]' alle Dateien, deren Name mit '.a' oder '.o' endet.

Diese Option wird akkumuliert, wenn Sie sie mehrmals angeben. Wenn Sie beispielsweise die Optionen -x 'RCS' -x '* verwenden, ignoriert v' alle Dateien oder Unterverzeichnisse, deren Basisname 'RCS' lautet oder mit ', v' endet.

Bis auf weiteres angehalten.
quelle
Meins (Ubuntu 10.04) hat diese Zeilen nicht. Ich habe es auch versucht und es hat nicht funktioniert. Ich denke das ist eine neue Version.
Alumi
21

Entnommen aus (einer Version von) der Manpage:

-x PAT  --exclude=PAT
  Exclude files that match PAT.

-X FILE    --exclude-from=FILE
  Exclude files that match any pattern in FILE.

Es sieht also so aus -x, als würde beim Melden nur ein Muster akzeptiert. Wenn Sie jedoch alle Muster, die Sie ausschließen möchten, in eine Datei einfügen (vermutlich eines pro Zeile), können Sie das zweite Flag wie folgt verwenden:

$ diff /destination/dir/1 /destination/dir/2 -r -X exclude.pats

wo exclude.pats ist:

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif
jamesbtate
quelle
3
Sie können alle Dateierweiterungen in Ihrem Ordner mit Ausnahme der Erweiterung <my-ext> mit der folgenden Befehlszeile finden:find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats
John
Ich wünschte, ich hätte Johns Kommentar früher bemerkt, aber bei macOs / bash bin ich zu einer ähnlichen Lösung gekommen, um die Ausschlussdatei mit mehreren Mustern zu erstellen: find . -not -name "*.c" -and -not -name "*.h" -and -type f -print0 | xargs -0 basename | grep -E '.*\..+' | sed 's/\./\//g' | xargs basename | xargs printf '*.%s\n' | sort | uniq > X-FILEIch möchte glauben, dass dies hilft, vielleicht auch unter Linux. (In diesem Beispiel ist eine Single -name "*.[ch]"in Ordnung, aber nicht sehr anschaulich)
Eruve
13

Sie können find auch mit -exec verwenden, um diff aufzurufen:

cd /destination/dir/1
find . -name *.xml -exec diff {} /destination/dir/2/{} \;
Alex Harui
quelle
7

Das Fehlen einer ergänzenden - einschließlich ....

Wir können eine Problemumgehung durchführen, eine Ausschlussdatei mit allen Dateien, außer dem, was wir einschließen möchten. Also erstellen wir file1mit einem Find alle Dateien, die keine Erweiterungen haben, die wir einschließen möchten, sedfangen den Dateinamen und sind nur:

diff --exclude-from=file1  PATH1/ PATH2/

Beispielsweise:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 
Sérgio
quelle
Super nützlicher Einzeiler, danke. Unter Mac OSX ist grep etwas anders und es wird find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar
3

Ich habe den folgenden Befehl verwendet, um den Unterschied aller *.tmplDateien zwischen DIR1und zu ermitteln DIR2. In meinem Fall hat dies keine Fehlalarme ergeben, aber es kann für Sie sein, abhängig vom Inhalt Ihres DIRS.

diff --brief DIR1 DIR2 | grep tmpl

Mikhail Golubitsky
quelle
2

Falls Sie es bequem finden, können Sie Folgendes verwenden Makefile. Einfach ausführen: "Patch erstellen"

#Makefile for patches

#Exlude following file endings
SUFFIX += o
SUFFIX += so
SUFFIX += exe
SUFFIX += pdf
SUFFIX += swp

#Exlude following folders
FOLDER += bin
FOLDER += lib
FOLDER += Image
FOLDER += models

OPTIONS = Naur

patch: 
    rm test.patch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
        org/ new/ > test.patch  

unpatch: 
    rm test.unpatch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
    new/ org/ > test.unpatch
Rafiz
quelle
1

Das Fehlen eines komplementären Einschlusses macht es notwendig, solche verschlungenen heuristischen Muster wie zu verwenden

*.[A-Zb-ik-uw-z]*

(meistens) Java-Dateien finden!

Jerry Miller
quelle
1

Wenn Sie verschiedene Quellen unterscheiden und einfach halten möchten:

diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"

Entfernen Sie das letzte grep, wenn Sie die Dateien abrufen möchten, die nur in einem der Pfade vorhanden sind.

Alex
quelle
0

Obwohl das tatsächliche diffVorhandensein anderer Dateien nicht vermieden wird, können Sie , wenn Sie eine Patch-Datei oder ähnliches erstellen möchten, filterdiffaus dem patchutilsPaket verwenden, z. B. nur Ihre .pyÄnderungen patchen :

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
Cez
quelle