GNU/Linux >> Znalost Linux >  >> Linux

Rozdíl -r pouze pro určité typy souborů?

Existuje způsob, jak mohu provést rekurzivní porovnání dvou adresářů, ale pouze porovnat (na jejich příslušných místech) soubory, které odpovídají konkrétnímu názvu souboru nebo predikátu typu souboru?

Např. Chtěl bych něco udělat jako

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

… nebo ještě lépe:

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

Je zřejmé, že použití diff není povinné jak předpokládám zaklínadlo s find a -exec diff by také mohlo stačit (jen nevím, jak vygenerovat doplňkové cesty k souborům v druhém případě).

Přijatá odpověď:

Shellscript differ-r

Tento skript shellu může provádět rekurzivní porovnání dvou adresářů, ale pouze porovnávat (na jejich příslušných místech) soubory, které odpovídají konkrétnímu souboru nebo vzoru typu souboru.

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

Ukázka

Soubory:

$ 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

Použití:

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

Spuštění differ-r :

Provedený diff příkazové řádky jsou vytištěny zeleným textem a výstup, pokud není shoda, je vytištěn s výchozím textem (bílá na černém na následujícím snímku obrazovky).

$ ./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 s filtrem

Pokud nepotřebujete získat žádný výstup popisující rozdíl, zjistěte pouze, které soubory se liší nebo chybí (takže rsync chcete zkopírovat), můžete použít následující příkazový řádek.

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

Ukázka

$ 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)

Pokud chcete čistý výstup bez řádků s komentářem a bez adresářů, můžete grep výstup takto,

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

Shellscript rsync-diff

Tento jednořádkový řádek lze vytvořit jako základní příkaz shellscriptu 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)$'

Linux
  1. Jak přesměrovat pouze Stderr?

  2. Najít pouze určité řetězce (doména) Rozbalit jiný soubor?

  3. Rsync dva typy souborů v jednom příkazu?

  1. Tabulka oprávnění pro soubor/adresář a typy uživatelů souborového systému

  2. K čemu slouží soubor .la libtool?

  3. Změřte místo na disku určitých typů souborů souhrnně

  1. Jak najdu soubory, které mají pouze určitá oprávnění pro vlastníka?

  2. Jak tarovat určité typy souborů ve všech podadresářích?

  3. sys/types.h:Žádný takový soubor nebo adresář