Commandes de tuyauterie après un xargs

38

HP-UX ***** B.11.23 U Licence utilisateur illimité **** ia64 ****

find . -type d -name *log* | xargs ls -la

me donne les noms de répertoires (ceux qui contiennent logle nom du répertoire) suivis de tous les fichiers de ce répertoire.

Les répertoires  /var/opt/SID/application_a/log/,  /var/opt/SID/application_b/log/,  /var/opt/SID/application_c/log/etc. contiennent des fichiers journaux.

Je veux que seuls les deux derniers fichiers de log soient listés par la lscommande, ce que je trouve habituellement avec ls -latr | tail -2.

La sortie doit être quelque chose comme ça ..

/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 -2ne me donne pas le résultat ci-dessus. Ce que je reçois est une liste des deux derniers fichiers de find . -type d -name *log* | xargs ls -lacommande.

Alors, puis-je diriger les commandes après une passe xargs? Sinon, comment interroger, pour obtenir la liste résultante des fichiers dans le format ci-dessus?

find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"

me donne une liste de dix noms de répertoire dans le répertoire actuel, ce /var/opt/SIDqui n’est pas ce que je veux.

une autre personne1
la source
2
Vous devriez citer le *log*cas contraire, le shell le développera.
Anthon
Sachez que sh -cle nom de la commande (paramètre 0) est attendu comme second argument. Vous devez donc toujours le faire find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail(remarquez-le lstailà la fin, qui servira comme $0pour le shell créé). Sinon, le premier de vos résultats remplira ce rôle et restera inutilisé.
Jonas

Réponses:

58

Tu es presque là. Dans votre dernière commande, vous pouvez utiliser-I pour faire le lsbon

-I replace-str

    Remplacez les occurrences de replace-str dans les arguments initiaux par des noms lus à partir de l'entrée standard. De plus, les espaces non cités ne terminent pas les éléments en entrée; au lieu de cela, le séparateur est le caractère de nouvelle ligne. Implique -xet -L 1.

Donc avec

find . -type d -name "*log*" | xargs -I {} sh -c "echo {}; ls -la {} | tail -2"

vous allez echotrouver le répertoire trouvé find, puis faites- ls | taille dessus.

fredtantini
la source
trouver . -type d -name " log " | xargs -I {} sh -c "echo {}; ls -ltr {} | grep -E \" file_in | file_out \ "| tail -5" J'ai utilisé celui-ci.
anotherperson1
3
Je fais avecxargs -n 1 sh -c 'echo $0'
Ginhing
1
sur macOS, le remplacement ne fonctionnait pas dans la commande citée, il echo $0était donc utile (et plus compréhensible)
mpuncel
1
Pour le faire fonctionner avec des noms de fichiers avec des espaces, utilisez -print0, xargs -0et échapper {}à des guillemets doubles à l' intérieur de la shcommande:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
Benedikt Köppel
J'utilise "xargs -n 1 sh -c" echo \ $ 0 | $ func "` si je dois utiliser la variable $ func
dieu
5

GNU Parallel facilite ce genre de tâches:

find . -type d -name "*log*" | parallel --tag "ls -la {} | tail -2"

Si vous ne souhaitez pas effectuer une installation complète de GNU Parallel, vous pouvez effectuer une installation minimale: http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Ole Tange
la source
2

Juste en plus de fredtantini et à titre de clarification générale (car les documents sont un peu déroutants):

Le xargs -I {}prendra les caractères '{}' de l'entrée standard et les remplacera par tout ce qui sortira du tube. Cela signifie que vous pouvez remplacer {}n'importe quelle combinaison de caractères (peut-être pour mieux adapter votre style de programmation préféré). Par exemple : xargs -I % sh -c "echo %". Si vous utilisez toujours le, xargs -I {}vous pouvez le remplacer par un xargs -iraccourci.

Le sh -cva dire à votre bash / shell de lire la prochaine commande à partir d’une chaîne et non de l’entrée standard. Donc, écrire sh -c "echo something"est équivalent à echo something.

La xargs -I {} sh -c "echo {}"lira l'entrée vous avez créé avec ce sh -cqui est echo {}. Depuis que vous lui avez dit de remplacer{} par les arguments du tuyau, c'est ce qui va arriver.

Vous pouvez facilement tester cela même sans tuyauterie, il vous suffit de taper la commande ci-dessus dans un terminal. Tout ce que vous écrivez ensuite sera envoyé au terminal (Ctrl-D pour sortir).

Dans la ls -la {}commande, la même chose se reproduit. Le {}est remplacé par le contenu de la commande de pré-pipe.

Borisu
la source