web-dev-qa-db-fra.com

Commandes de canalisation après un xargs canalisé

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

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

me donne les noms des répertoires (ceux qui contiennent log dans le 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/ et ainsi de suite contiennent des fichiers journaux.

Je souhaite que seuls les deux derniers fichiers journaux soient répertoriés par la commande ls, que je trouve généralement en utilisant 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 -2 ne me donne pas le résultat ci-dessus. Ce que j'obtiens est une liste des deux derniers fichiers de find . -type d -name *log* | xargs ls -la commande.

Puis-je diriger des commandes après un xargs canalisé? Sinon, comment demander 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épertoires dans le répertoire courant qui se trouve être /var/opt/SID et ce n'est pas non plus ce que je veux.

44
anotherperson1

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

-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 entre guillemets ne terminent pas les éléments d'entrée; à la place, 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 echo le répertoire trouvé par find, puis faites ls | tail dessus.

68
fredtantini

GNU Parallel facilite ce genre de tâches:

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

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

5
Ole Tange

Juste en plus de fredtantini et comme 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 sort du tube. Cela signifie que vous pouvez réellement remplacer {} avec n'importe quelle combinaison de caractères (peut-être pour mieux adapter votre saveur de programmation préférée). Par exemple: xargs -I % sh -c "echo %". Si vous utilisez toujours le xargs -I {} vous pouvez le remplacer par xargs -i car c'est la sténographie.

Le sh -c indiquera à votre bash/Shell de lire la prochaine commande à partir d'une chaîne et non à partir de l'entrée standard. Donc, en écrivant sh -c "echo something" est équivalent à echo something.

Le xargs -I {} sh -c "echo {}" lira l'entrée que vous avez créée avec sh -c lequel est echo {}. Puisque vous lui avez dit de remplacer {} avec les arguments que vous avez tirés de la pipe, c'est ce qui va arriver.

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

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

4
Borisu