Ce qui suit devrait fonctionner sur absolument tous les chemins.
Déclarer une fonction pour pouvoir utiliser head
et tail
sur la sortie séparée par NUL :
nul_terminated() {
tr '\0\n' '\n\0' | "[email protected]" | tr '\0\n' '\n\0'
}
Ensuite, vous pouvez l'utiliser pour obtenir une liste de chemins séparés par NUL à partir de votre recherche après avoir traversé tail
:
find . -exec printf '%s\0' {} \; | nul_terminated tail -n 2
Vous pouvez ensuite diriger cela vers xargs
et ajoutez vos options :
find . -iname "*FooBar*" -exec printf '%s\0' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
Explication :
find
fichiers dans le répertoire courant (.
) et ci-dessous avec un nom contenantfoobar
(insensible à la casse à cause dui
en-iname
);- pour chaque fichier, exécutez (
-exec
) une commande pour - imprimer chaque chemin de fichier (
{}
) suivi d'un caractère NUL (\0
) individuellement (\;
); - échanger les nouvelles lignes et les caractères NUL (
tr '\0\n' '\n\0'
);" - obtenir les deux dernières lignes (c'est-à-dire les chemins ;
tail -n 2
,"[email protected]"
); - échangez à nouveau les nouvelles lignes et les caractères NUL pour obtenir une liste de noms de fichiers séparés par NUL (
tr '\0\n' '\n\0'
).
Le xargs
la commande est un peu plus difficile à expliquer. Il construit autant de cp ... "dest"
commandes nécessaires pour tenir dans la longueur maximale de commande du système d'exploitation, en remplacement du {}
jeton dans la commande avec le nom de fichier réel (-I "{}" ... "{}"
), en utilisant le caractère NUL comme séparateur lors de la lecture des paramètres (-0
).
Vous pouvez essayer
cp $(find . -iname "*FooBar*" | tail -2 ) dest
find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
Malheureusement, cela ne fonctionnera pas avec les noms de fichiers contenant des espaces ou des retours à la ligne.