Bash: Porovnání verzí
m typo |
|||
| Řádek 36: | Řádek 36: | ||
cmp -l $SRC/$i $TRG/$i | cmp -l $SRC/$i $TRG/$i | ||
done | done | ||
</pre> | |||
=== Příkazy for, if, find, md5sum, awk, cmp a sqlite3 === | |||
Skript prohledá zadné akresáře a vytvoří seznam duplicitní souborů, tj. identických souborů nacházejících se v různých adresářích. Implicitně hledá duplicity v běžném adresáři. Pro všechny nalezené soubory nejprve skript vypočítá jejich kontrolní součty (<code>md5sum</code>), v databázi <code>sqlite</code> je agreguje, soubory se stejnými md5 součty porovná příkazem <code>cmp</code> a vytvoří jejich seznam. | |||
<pre> | |||
#!/bin/bash | |||
LIST="/tmp/$$-duplicate-files" | |||
rm -f $LIST.* | |||
if [ "$1" == "" ]; then | |||
DIRS=. | |||
else | |||
DIRS="$1 $2 $3 $4 $5 $6 $7 $8 $9" | |||
fi | |||
cat <<EOF >$LIST.awk | |||
{ print "INSERT INTO df VALUES ('" \$1 "', '" \$2 "');" } | |||
EOF | |||
sqlite3 $LIST.db "CREATE TABLE df (md5 char(32), file text)"; | |||
for d in $DIRS | |||
do | |||
for f in $(find $d -type f | grep -v "\ " | grep -v "(" | grep -v \/CVS\/ ) | |||
do | |||
md5sum $f | awk -f $LIST.awk | sqlite3 $LIST.db | |||
done | |||
done | |||
cat <<EOF > $LIST.sql | |||
DELETE FROM df WHERE md5 IN | |||
(SELECT md5 | |||
FROM df | |||
GROUP BY md5 | |||
HAVING count(file) = 1); | |||
SELECT a.file, b.file | |||
FROM df AS a | |||
JOIN | |||
df AS b | |||
ON a.md5 = b.md5 AND a.file < b.file | |||
ORDER BY a.md5; | |||
EOF | |||
cat <<EOF > $LIST.awk | |||
{print "if cmp -s " \$1 " " \$2 " ; then echo cmp " \$1 " " \$2 "; fi" } | |||
EOF | |||
sqlite3 $LIST.db < $LIST.sql | awk -F \| -f $LIST.awk | bash | |||
rm -f $LIST.* | |||
</pre> | </pre> | ||
Verze z 1. 5. 2009, 21:41
Bash je shell, tj. příkazový interpret, který je součástí operačního systému GNU.
Ukázky a příklady
Příkazy find, sed, grep, case, echo a cmp
Bash skript pro porovnání dvou adresářů s ošetřením jmen souborů obsahujících mezery, odfiltrováním skrytých souborů a rotující vrtulkou jako indikátorem průběhu zpracování (ukázka použití příkazu case).
#!/bin/bash
SRC=amonit-2009-04-29
TRG=amonit-CD
FILES=$(cd $SRC && find -type f | sed s/\ /?/g | grep -v /\\. )
c=-
for i in $FILES
do
case $c in
-)
c=\\
;;
\\)
c=\|
;;
\|)
c=/
;;
/)
c=-
;;
esac
echo -en "\b$c"
cmp -l $SRC/$i $TRG/$i
done
Příkazy for, if, find, md5sum, awk, cmp a sqlite3
Skript prohledá zadné akresáře a vytvoří seznam duplicitní souborů, tj. identických souborů nacházejících se v různých adresářích. Implicitně hledá duplicity v běžném adresáři. Pro všechny nalezené soubory nejprve skript vypočítá jejich kontrolní součty (md5sum), v databázi sqlite je agreguje, soubory se stejnými md5 součty porovná příkazem cmp a vytvoří jejich seznam.
#!/bin/bash
LIST="/tmp/$$-duplicate-files"
rm -f $LIST.*
if [ "$1" == "" ]; then
DIRS=.
else
DIRS="$1 $2 $3 $4 $5 $6 $7 $8 $9"
fi
cat <<EOF >$LIST.awk
{ print "INSERT INTO df VALUES ('" \$1 "', '" \$2 "');" }
EOF
sqlite3 $LIST.db "CREATE TABLE df (md5 char(32), file text)";
for d in $DIRS
do
for f in $(find $d -type f | grep -v "\ " | grep -v "(" | grep -v \/CVS\/ )
do
md5sum $f | awk -f $LIST.awk | sqlite3 $LIST.db
done
done
cat <<EOF > $LIST.sql
DELETE FROM df WHERE md5 IN
(SELECT md5
FROM df
GROUP BY md5
HAVING count(file) = 1);
SELECT a.file, b.file
FROM df AS a
JOIN
df AS b
ON a.md5 = b.md5 AND a.file < b.file
ORDER BY a.md5;
EOF
cat <<EOF > $LIST.awk
{print "if cmp -s " \$1 " " \$2 " ; then echo cmp " \$1 " " \$2 "; fi" }
EOF
sqlite3 $LIST.db < $LIST.sql | awk -F \| -f $LIST.awk | bash
rm -f $LIST.*