On Wed, 16 Jan 2002, Christian Boltz wrote:
Am Mittwoch, 16. Januar 2002 08:22 schrieb Juergen Schwarting:
* Am 15.01.2002 um 23:56 Uhr schrieb Christian Boltz: [..]
Grundgedanke ist der folgende: diff-Ausgabe in eine Datei umleiten [1], diese mit while und read $1 $2 $3 $4 $5 zeilenweise einlesen, dann - falls $1 = "Files" -> Datei geändert -> $2 [2] ins Changed-Verzeichnis - falls $1 = "Only" und $3 = "verz_a" -> neue Datei -> $4 ins Changed-Verz. - falls $1 = "Only" und $3 = "verz_b" -> gelöschte Datei -> Hinweis ausgeben
[1] sollte auch mit einer Pipe gehen, oder? [2] "verz_a/" muss ich natürlich aus $2 herauslöschen lassen. TEST=`echo "verz_a" | cut -c 7-` sollte das erledigen.
zu [1]
diff -r -q verz_a/ verz_b/ | while read Zeile; do set -- $Zeile echo "$1 # $2 # $3 # $4 # $5" # nur als Beispiel
$ cd /tmp/test $ mkdir "test verz" $ mkdir verz_b (beide ein bisschen gefuellt) $ diff -rq diff -rq test\ verz/ verz_b/ [..] Only in verz_b/: configure Files test verz/configure.in and verz_b/configure.in differ Only in test verz/: configure.in~ [..] $ diff -rq test\ verz/ verz_b/ | while read zeile; do set -- $zeile; echo "$1 # $2 # $3 # $4 # $5"; done [..] Only # in # verz_b/: # configure # Files # test # verz/configure.in # and # verz_b/configure.in Only # in # test # verz/: # configure.in~ [..]
Die letzten 2 Zeilen habe ich zwar noch nicht ganz verstanden, aber sie scheinen zu funktionieren ;-)
s.o. Nur ohne Leerzeichen (und andere Sonderzeichen). Die erste Variablen $1 bis ... beinhalten die Kommandozeilenargumente. Mit "set --" koennen diese "neu befuellt" werden. Ein 1=x geht nicht. Zu while read zeile -> siehe "help read" aus man bash, "read variable" liest die Standardeingabe zeilenweise und packt die jew. zeile in die variable. Das echo sollte klar sein. Halbwegs robust ist IMO folgendes, mit dem ich gestern angefangen habe, ist aber noch sehr unvollstaendig und ich hatte dich auch flasch verstanden, was du wo haben willst, bietet aber hoffentlich ein paar Ideen, wie du die jew. Zeilen auswerten kannst. Achso, ist glaube ich weniger performant, aber dafuer glaube ich recht portabel... ==== dirdiff.sh ==== #! /bin/bash DIFF="/usr/bin/diff" GREP="/usr/bin/grep" SED="/usr/bin/sed" CP="echo /bin/cp -i" ## erstmal mit echo entschaerft RM="echo /bin/rm -i" ## erstmal mit echo entschaerft usage="Usage: `basename $0` Verz_eins Verz_zwei" if test "x$#" != "x2"; then echo "$usage"; exit 1; fi dir_OLD="$1" dir_NEW="$2" test -d "$dir_OLD" && test -d "$dir_NEW" || exit 1 function parse() { while read "line"; do if echo "$line" | $GREP -q '^Files.*differ$'; then ## Achtung: das ist "anfaellig gegen Dateinamen wie z.B.: ## 'XXX and YYY' und 'Files XXX' und 'XXX differ' etc. ## die naechste Zeile sollte letztere beiden Probleme loesen, ## aber Datei-/Verzeichnisnamen mit ' and ' sind wohl kaum ## automatisch aufzuloesen... Das folgende grep sollte diese ## Faelle aber erkennen koennen. if echo "$line" | $GREP -q ' and .* and '; then echo "Uhoh, filename conflict!" >&2 echo "$line" >&2 else line=`echo "$line" | $SED 's¡^Files ¡¡;s¡differ$¡¡'` oldfile=`echo "$line" | $SED 's¡Files \(.*\) and .*¡\1¡'` newfile=`echo "$line" | $SED 's¡Files .* and \(.*\) differ$¡\1¡'` echo "'$oldfile' <-> '$newfile'" ## mach was mit den unterschiedlichen Dateien... z.B. ein ## diff -u $oldfile $newfile > "$andersdir.$oldfile.diff" ## oder sowas in der Art... fi else if echo "$line" | $GREP -q '^Only' then dir=`echo "$line" | $SED 's¡Only in \([^:]*\):.*¡\1¡'` file=`echo "$line" | $SED 's¡Only in .*: \(.*\)$¡\1¡'` case "$dir" in $dir_OLD*) $CP "${dir}/${file}" "${dir_NEW}/${file}" ;; $dir_NEW*) $RM "${dir_NEW}/${file}" ;; *) echo "Uhoh, whot's this?" >&2 exit 1 ;; esac fi fi done } $DIFF -rq "$dir_OLD" "$dir_NEW" | parse ==== EOF ====
echo ${Zeile#verz_a/} # entfernt 'verz_a/' aus der Zeile
hiermit spart man sich den Aufruf des externen <cut> ;-)
netter Trick ;-) Danke für die Tips!
Siehe man bash, Abschnitt "Brace Expansion"...
So langsam wird es wohl Zeit für einen Ausdruck der man bash...
*hehe* -dnh -- Lusers. Can't live with 'em, can't run 'em over in the car park and make it look like an accident... -- Chris King