J'ai un script bash pour déployer du code depuis un environnement bêta vers un environnement de production mais actuellement je dois ajouter la liste des fichiers à un fichier txt de manière manaully et parfois j'en manque. Fondamentalement, mon script de déploiement cat/loops copie les fichiers. (exportations/importations db également 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:
trouver . -type f -mtime -14> deploy.txt
Voici la ligne que les chats 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
Avez-vous une idée de comment accomplir cela en utilisant le script bash?
Merci!
Vous pouvez utiliser le -printf
option de ligne de commande avec %f
pour afficher uniquement le nom du fichier sans aucune information de 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
Le ./
devrait être inoffensif. La plupart des programmes traiteront /foo/bar
et /foo/./bar
comme équivalent. Je me rends compte que cela n'a pas l'air très agréable, mais d'après ce que vous avez publié, je ne vois aucune raison pour laquelle cela entraînerait l'échec de votre script.
Si vous voulez vraiment l'enlever, sed
est probablement le moyen le plus propre:
find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt
Si vous utilisez 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é sur la ligne de commande, jusqu'à et y compris la première barre oblique. Cela préservera tous les sous-répertoires de votre structure de répertoires.
Pourquoi avez-vous besoin de supprimer le ./
? C'est valable d'avoir dans un chemin. Donc
cp -i dir1/./somefile dir2/./somefile
c'est juste ok!
Mais si vous souhaitez supprimer le nom du répertoire dans find, vous pouvez utiliser le %P
arg à -printf
.
man find (1) dit:
%P File's name with the name of the command line argument under which it was found removed.
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
La solution "find -printf" ne fonctionnera pas sur FreeBSD car find n'a pas une telle option. Dans ce cas, AWK peut vous aider. Il renvoie un nom de famille ($ NF), donc il peut fonctionner sur n'importe quelle profondeur.
find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'
PS: extrait du livre de D.Tansley "Programmation Linux et Unix Shell"
Eh bien, vous avez quelques options. Vous pouvez utiliser le -printf
option dans find pour imprimer uniquement le nom du fichier, ou vous pouvez utiliser un outil comme sed pour simplement supprimer ./
.
# simply print out the filename, will break if you have sub-directories.
find . -mtime -14 -printf '%f\n'
# strip a leading ./
find . -mtime -14 | sed -e 's/^\.\///'
Une solution rapide, si je comprends bien la question, utilise cut
sur la sortie de la commande find
:
$> find . -type f -mtime -14 | cut -b 3- > deploy.txt
Cela supprimera le premier aux caractères de chaque ligne du résultat (dans votre cas, ./
). Probablement pas la meilleure solution, mais fonctionne dans votre scénario.
sed
est parfait pour ce genre de chose.
$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt
Je ne sais pas de quel type de nom de fichier nous parlons, mais tout ce qui comporte des espaces ou des nouvelles lignes met en danger la plupart des solutions.
Ma suggestion serait d'utiliser l'expansion des paramètres de Shell pour supprimer les caractères de chaque nom de fichier:
find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt
Si vous aimez vraiment les pipes, vous pouvez utiliser un délimiteur "sûr", comme un null, avec xargs pour recevoir chaque nom de fichier:
find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt
N'oubliez pas que la sortie de ceci est PAS délimitée par des valeurs nulles, donc bien que cela puisse être suffisant pour une vérification du globe oculaire, aucune de ces solutions ne produit un fichier deploy.txt qui est sûr à utiliser pour l'automatisation, sauf si vous êtes très confiant sur vos noms de fichiers source.