it-swarm.com.de

find -exec mit mehreren Befehlen

Ich versuche, find -exec mit mehreren Befehlen ohne Erfolg zu verwenden. Weiß jemand, ob Befehle wie die folgenden möglich sind?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

Grundsätzlich versuche ich, die letzte Zeile jeder txt-Datei im aktuellen Verzeichnis und am Ende der Zeile ein Komma gefolgt vom Dateinamen zu drucken.

383
Andy

find akzeptiert mehrere -exec Teile für den Befehl. Zum Beispiel:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

Beachten Sie, dass in diesem Fall der zweite Befehl nur ausgeführt wird, wenn der erste erfolgreich zurückgegeben wird, wie von @Caleb erwähnt. Wenn Sie möchten, dass beide Befehle unabhängig von ihrem Erfolg oder Misserfolg ausgeführt werden, können Sie das folgende Konstrukt verwenden:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;
576
Tinker
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
83
Avari

Einer der folgenden:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;
47

Ein anderer Weg ist wie folgt:

multiple_cmd() { 
    tail -n1 $1; 
    ls $1 
}; 
export -f multiple_cmd; 
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

in einer Zeile

multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • "multiple_cmd()" - ist eine Funktion
  • "export -f multiple_cmd" - exportiert es, damit es von jeder anderen Unterschale gesehen werden kann
  • "find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - Findet, dass die Funktion in Ihrem Beispiel ausgeführt wird

Auf diese Weise kann multiple_cmd beliebig lang und komplex sein.

Hoffe das hilft.

15
Al3x

Es gibt einen einfacheren Weg:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

Alternative:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"
8
Camilo Martin

Ich weiß nicht, ob Sie dies mit find tun können, aber eine alternative Lösung wäre, ein Shell-Skript zu erstellen und dieses mit find auszuführen.

lastline.sh:

echo $(tail -1 $1),$1

Machen Sie das Skript ausführbar

chmod +x lastline.sh

Verwenden Sie find:

find . -name "*.txt" -exec ./lastline.sh {} \;
7

Die erste Antwort von Denis ist die Antwort, um das Problem zu lösen. Tatsächlich handelt es sich jedoch nicht mehr um einen Fund mit mehreren Befehlen in nur einem Exec, wie der Titel vermuten lässt. Um den einen Exec mit mehreren Befehlen zu beantworten, müssen wir nach etwas anderem suchen, um es aufzulösen. Hier ist ein Beispiel:

Behalten Sie die letzten 10000 Zeilen von .log-Dateien bei, die in den letzten 7 Tagen mithilfe von 1 exec-Befehl mit mehreren {} Verweisen geändert wurden

1) sehen Sie, was der Befehl für welche Dateien tun wird:

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2) Mach es: (beachte nicht mehr "\>" sondern nur ">" das ist erwünscht)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

4
Eric Duruisseau

Dank Camilo Martin konnte ich eine verwandte Frage beantworten:

Was ich tun wollte, war

find ... -exec zcat {} | wc -l \;

was nicht funktioniert hat. Jedoch,

find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done

funktioniert, also danke!

4
Greg Dougherty

sollte xargs benutzen :)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

ein anderer (arbeitet an osx)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'
1
smapira