HP-UX ***** B.11.23 U ia64 **** Lizenz für unbegrenzte Benutzer
find . -type d -name *log* | xargs ls -la
gibt mir die Verzeichnisnamen (die log
im Verzeichnisnamen enthalten sind ), gefolgt von allen Dateien in diesem Verzeichnis.
Die Verzeichnisse /var/opt/SID/application_a/log/
, /var/opt/SID/application_b/log/
, /var/opt/SID/application_c/log/
usw. Protokolldateien enthalten.
Ich möchte, dass nur die zwei neuesten Protokolldateien vom ls
Befehl aufgelistet werden , den ich normalerweise verwende ls -latr | tail -2
.
Die Ausgabe muss ungefähr so sein ..
/var/opt/SID/application_a/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
find . -type d -name *log* | xargs ls -la | tail -2
gibt mir das obige ergebnis nicht. Was ich bekomme, ist eine Liste der letzten beiden
find . -type d -name *log* | xargs ls -la
Befehlsdateien.
Kann ich also Befehle nach einer Pipe weiterleiten xargs
? Wie frage ich sonst ab, um die resultierende Liste der Dateien im obigen Format zu erhalten?
find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"
gibt mir eine liste von zehn verzeichnisnamen innerhalb des aktuellen verzeichnisses was zufällig ist /var/opt/SID
und das ist auch nicht was ich will.
*log*
sonst wird die Shell es erweitern.sh -c
dass der Befehlsname (Parameter 0) als zweites Argument erwartet wird. Dies sollten Sie immer tunfind . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail
(beachten Sie daslstail
am Ende, das$0
für die erstellte Shell verwendet wird). Andernfalls wird das erste Ihrer Ergebnisse diese Rolle ausfüllen und nicht verwendet.Antworten:
Du bist fast am Ziel. In Ihrem letzten Befehl können Sie verwenden
-I
, um dasls
richtig zu tunAlso mit
du wirst
echo
das dir durch findenfind
, dann mach dasls | tail
drauf.quelle
xargs -n 1 sh -c 'echo $0'
echo $0
-print0
,xargs -0
und die Flucht{}
in doppelte Anführungszeichen innerhalb dessh
Befehls:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
GNU Parallel macht diese Art von Aufgaben einfach:
Wenn Sie GNU Parallel nicht vollständig installieren möchten, können Sie eine Minimalinstallation durchführen: http://git.savannah.gnu.org/cgit/parallel.git/tree/README
quelle
Nur zusätzlich zu fredtantini und zur allgemeinen Verdeutlichung (da die Dokumente etwas verwirrend sind):
Das
xargs -I {}
nimmt die '{}' Zeichen von der Standardeingabe und ersetzt sie durch alles, was von der Pipe hereinkommt. Dies bedeutet, dass Sie tatsächlich durch eine{}
beliebige Zeichenkombination ersetzen können (möglicherweise, um Ihrem bevorzugten Programmierstil besser zu entsprechen). Zum Beispiel :xargs -I % sh -c "echo %"
. Wenn Sie immer die verwendenxargs -I {}
, können Siexargs -i
sie durch die Kurzschrift ersetzen .Das
sh -c
wird zeigen , Ihre bash / Shell den nächsten Befehl aus einer Zeichenfolge zu lesen und nicht von der Standardeingabe. Schreibensh -c "echo something"
ist also gleichbedeutend mitecho something
.Das
xargs -I {} sh -c "echo {}"
liest die Eingabe, mitsh -c
der Sie erstellt habenecho {}
. Da Sie es angewiesen haben, es durch{}
die Argumente zu ersetzen, die Sie aus der Pipe erhalten haben, wird das passieren.Sie können dies auch ohne Verrohrung problemlos testen. Geben Sie einfach den obigen Befehl in ein Terminal ein. Was auch immer Sie als Nächstes schreiben, wird an das Terminal ausgegeben (Strg-D zum Beenden).
Im
ls -la {}
Befehl passiert dasselbe noch einmal. Das{}
wird durch den Inhalt des Pre-Pipe-Befehls ersetzt.quelle