web-dev-qa-db-fra.com

trouver -exec avec plusieurs commandes

J'essaie d'utiliser find -exec avec plusieurs commandes sans aucun 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 du répertoire actuel et d'imprimer à la fin de la ligne une virgule suivie du nom du fichier.

383
Andy

find accepte plusieurs _-exec_ parties à 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 la première retourne avec succès, comme mentionné par @Caleb. Si vous voulez que les deux commandes s'exécutent indépendamment de leur succès ou de leur échec, vous pouvez utiliser cette construction:

_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

L'un des 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"' _ {} \;
47
Dennis Williamson

Une autre façon est comme ça:

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

en 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"' {} \;" - trouver qui exécutera la fonction sur votre exemple

Ainsi, multiple_cmd peut être aussi long et complexe que vous le souhaitez.

J'espère que cela t'aides.

15
Al3x

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 ...)"
8
Camilo Martin

Je ne sais pas si vous pouvez faire cela 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 {} \;
7
Andrea Spadaccini

La première réponse de Denis est la réponse pour résoudre le problème. Mais en réalité ce n’est plus une découverte avec plusieurs commandes dans un seul exec comme le suggère le titre. Pour répondre à l'exécutif avec plusieurs commandes, nous devrons rechercher autre chose à résoudre. Voici un exemple:

Conserve les 10000 dernières lignes de fichiers .log modifiés au cours des 7 derniers jours à l'aide d'une commande exec à l'aide de 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: (ne notez plus "\>" mais seulement ">" c'est voulu)

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

4
Eric Duruisseau

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!

4
Greg Dougherty

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 ' ' '/'
1
smapira