2016-06-21 11 views
1

Ich fand ein unerwartetes Verhalten von "find -exec" bash Befehl und ich würde eine Interpretation zu schätzen wissen. Der gleiche Job kann mit "for file_name in find ....; tun ...." Schleife, so ist die Frage, warum es nicht funktioniert mit -exec Option zu finden.Unerwartetes Verhalten von find -exec

Es gibt zwei Ordner (SRC/und src /) mit demselben Satz von Dateien. Ich mag die Dateien in diesen Ordnern vergleichen:

find src/ -type f -exec sh -c "diff {} `echo {} | sed 's/src/SRC/'`" \; 

dies jedoch nicht vergleichen, die Dateien ... aus irgendeinem Grunde sed Befehl macht nicht das die Substitution. Wenn es nur eine Datei, zB „a“, in jedem dieser Ordner dann ein Befehl

find src/ -type f -exec sh -c "echo {} `echo {} | sed 's/src/SRC/'`" \; 

Ausgänge

src/a src/a 

wenn man tut eine ähnliche Sache in bash, alle folgenden Befehle geben das gleiche Ergebnis (SRC/a):

echo src/a | sed 's/src/SRC/' 
echo `echo src/a | sed 's/src/SRC/'` 
sh -c "echo src/a | sed 's/src/SRC/'" 
sh -c "echo `echo src/a | sed 's/src/SRC/'`" 

aber wenn diese Befehle werden an "finden exec ..." die Ausgänge sind unterschiedlich:

find src/ -type f -exec bash -c "echo {} | sed 's/src/SRC/'" \; 

gibt "SRC/a"

und

find src/ -type f -exec bash -c "echo `echo {} | sed 's/src/SRC/'`" \; 

gibt "src/a"

Ist das das erwartete Verhalten?

+4

Warum Sie nicht verwenden 'diff -r SRC src'? – GMichael

+0

Escape '\' '' '\\' ' – anishsane

+0

@Michael, das ist ein guter Punkt, aber es beantwortet meine Frage nicht. Um deine Frage zu beantworten: Ursprünglich wollte ich am Ende etwas erreichen, das an emacs -q --eval erinnert (ediff-merge-files "file2" "file2"), aber merkte, dass etwas nicht stimmt mit find ... Dann reduziert auf dieses Beispiel .... – Mitya

Antwort

1

Verwenden Sie einfache Anführungszeichen für sh -c für das Skript wird zuerst von Ihrer Shell interpretiert. Und führen Sie den Dateinamen als Argument für sh statt {} innerhalb der Anführungszeichen verwendet:

find src/ -type f -exec sh -c 'diff "$1" "$(printf "%s\n" "$1" | sed "s/src/SRC/")"' _ {} \; 

Oder mit bash:

find src/ -type f -exec bash -c 'diff "$1" "${1/src/SRC}"' _ {} \; 
+0

Ich mochte die zweite Methode +1 – sjsam

+1

Sie brauchen wirklich nicht Bash in diesem sehr speziellen Fall: 'find src/-type f -exec sh -c 'diff" $ 1 "" SRC $ {1 # src} "' _ {} \; ' –