50 votes

Supprimer le chemin de la sortie de la commande find

J'ai un script bash pour déployer du code d'un environnement bêta vers un environnement de production mais actuellement je dois ajouter la liste des fichiers à un fichier txt manuellement et parfois j'en oublie certains. Fondamentalement, mon script de déploiement cat/boucles copie les fichiers. (exporte/importe également la base de données mais ce n'est pas pertinent..lol)

Quoi qu'il en soit, j'aimerais utiliser la commande find pour générer une liste de fichiers modifiés au cours des 14 derniers jours. Le problème est que je dois supprimer le chemin ./ pour que le script de déploiement fonctionne.

Voici un exemple d'utilisation de la commande find :

find . -type f -mtime -14 > deploy.txt

Voici la ligne qui cat deploy.txt dans mon script de déploiement :

for i in `cat deploy.txt`; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done

Une idée de comment réaliser cela en utilisant un script bash ?

Merci !

56voto

user9517 Points 113163

Vous pouvez utiliser l'option de ligne de commande -printf avec %f pour imprimer uniquement le nom de fichier sans aucune information sur le répertoire

find . -type f -mtime -14 -printf '%f\n' > deploy.txt

ou vous pouvez utiliser sed pour simplement supprimer le ./

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt

15voto

James Sneeringer Points 6645

Le ./ devrait être inoffensif. La plupart des programmes considéreront /foo/bar et /foo/./bar comme équivalents. Je réalise que cela ne semble pas très esthétique, mais d'après ce que vous avez posté, je ne vois aucune raison pour laquelle cela pourrait provoquer l'échec de votre script.

Si vous voulez vraiment le supprimer, sed est probablement le moyen le plus propre :

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt

Si vous êtes sur un système avec GNU find (par exemple la plupart des systèmes Linux), vous pouvez le faire en une seule fois avec find -printf :

find . -type d -mtime 14 -printf "%P\n" > deploy.txt

Le %P renvoie le chemin complet de chaque fichier trouvé, moins le chemin spécifié en ligne de commande, jusqu'à et y compris le premier slash. Cela préservera tous les sous-répertoires dans votre structure de répertoire.

7voto

TrueY Points 179

Pourquoi avez-vous besoin de retirer le ./? C'est valide dans un chemin. Donc

cp -i dir1/./somefile dir2/./somefile

est juste correct!

Mais si vous souhaitez supprimer le nom du répertoire dans la recherche, vous pouvez utiliser l'argument %P avec -printf.

man find(1) dit:

         %P     Nom du fichier avec le nom de l'argument de la ligne de commande
                 sous lequel il a été trouvé supprimé.

Un exemple

$ find other -maxdepth 1
other
other/CVS
other/bin
other/lib
other/doc
other/gdbinit
$ find other -maxdepth 1 -printf "%P\n"

CVS
bin
lib
doc
gdbinit

Attention à la première ligne vide! Si vous voulez l'éviter, utilisez -mindepth 1

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit

7voto

user221341 Points 71

La solution "find -printf" ne fonctionnera pas sur FreeBSD car find n'a pas une telle option. Dans ce cas, AWK peut aider. Il renvoie un dernier nom ($NF), donc il peut fonctionner à n'importe quelle profondeur.

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'

PS : extrait du livre "Linux et Unix shell programming" de D.Tansley

4voto

jammus Points 1796

Eh bien vous avez quelques options. Vous pourriez utiliser l'option -printf dans find pour afficher uniquement le nom du fichier, ou vous pourriez utiliser un outil comme sed pour simplement supprimer le ./.

# imprime simplement le nom du fichier, va poser problème si vous avez des sous-répertoires.
find . -mtime -14 -printf '%f\n'

# supprime un ./
find .  -mtime -14 | sed -e 's/^\.\///'

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X