trouver -exec avec plusieurs commandes

J’essaie d’utiliser find -exec avec plusieurs commandes sans succès. Est-ce que quelqu’un sait si des commandes telles que les suivantes sont possibles?

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

Fondamentalement, j’essaie d’imprimer la dernière ligne de chaque fichier txt dans le répertoire en cours et d’imprimer à la fin de la ligne, une virgule suivie du nom du fichier.

find accepte plusieurs parties -exec à la commande. Par exemple:

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

Notez que dans ce cas, la deuxième commande ne sera exécutée que si le premier retourne avec succès, comme indiqué par @Caleb. Si vous souhaitez que les deux commandes s’exécutent indépendamment de leur réussite ou de leur échec, vous pouvez utiliser cette construction:

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

Un des éléments suivants:

 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"' _ {} \; 

Il y a un moyen plus simple:

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

Alternativement:

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

Une autre façon est comme ceci:

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

dans une ligne

 multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \; 
  • multiple_cmd() ” – est une fonction
  • export -f multiple_cmd ” – l’exportera pour que tout autre sous-shell puisse le voir
  • find *.txt -exec bash -c 'multiple_cmd "$0"' {} \; ” – recherche qui exécutera la fonction sur votre exemple

De cette façon, multiple_cmd peut être aussi long et complexe que nécessaire.

J’espère que cela t’aides.

Je ne sais pas si vous pouvez le faire avec find, mais une autre solution serait de créer un script shell et de l’exécuter avec find.

lastline.sh:

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

Rendre le script exécutable

 chmod +x lastline.sh 

Utilisez find :

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

La 1ère réponse de Denis est la réponse pour résoudre le problème. Mais en fait, ce n’est plus une trouvaille avec plusieurs commandes dans un seul exec comme le suggère le titre. Pour répondre à un seul exécutant avec plusieurs commandes, nous devons chercher autre chose à résoudre. Voici un exemple:

Conservez les 10000 dernières lignes de fichiers .log modifiées au cours des 7 derniers jours à l’aide de la commande 1 exec utilisant plusieurs références {}

1) voir ce que la commande fera sur quels fichiers:

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

2) Faites-le: (notez plus “\>” mais seulement “>” ceci est voulu)

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

Grâce à Camilo Martin, j’ai pu répondre à une question connexe:

Ce que je voulais faire était

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

qui n’a pas fonctionné. cependant,

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

ça marche, alors merci!

devrait utiliser xargs 🙂

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

un autre (travaillant sur osx)

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