6
votes

Rechercher des annuaires avec Rechercher dans Bash à l'aide d'une liste d'exclusion

Maintenant avant de penser, "cela a été fait avant" s'il vous plaît lisez sur.

Comme la plupart des personnes qui tentent de faire un script de recherche Bash, vous finissez par codage du script à une seule commande ligne, mais finissez par édition de la chose au cours des mois / années suivantes si souvent que vous le souhaitez à la fin a-t-il bien fait la première fois.

J'écris un petit programme de sauvegarde en ce moment pour faire des sauvegardes de répertoires et devez les trouver, contre une liste de Direcleie's à exclure. Plus facile à dire qu'à faire. Laissez-moi régler la scène: xxx

maintenant à la fin de celle-ci, vous obtenez / cgi-bac, / TMP, / test, / html, / icônes Cela prouve que le concept fonctionne, mais maintenant de le prendre un peu plus loin, j'ai besoin d'utiliser la recherche pour rechercher le basepath et rechercher un seul niveau profond pour tous les sous-répertoires et exclure la liste des sous-répertoires dans le tableau. ..

Si je tape ceci à la main, il serait: xxx

et devrais-je peut-être boucler dans chaque sous-répertoire et faire de même .. . J'espère que tu auras mon point.

Alors, ce que j'essaie de faire semblant possible, mais j'ai un peu de problème, printf ",% s" ne Comme moi en utilisant toutes ces options de découverte ou -o. Cela signifie-t-il que je dois utiliser EVAL à nouveau?

J'essaie d'utiliser la puissance de bash ici, et pas d'autres pour la boucle. Toute entrée constructive serait appréciée.


3 commentaires

Vous n'avez pas besoin de déclarer -a , l'affectation suffit. Les noms de variables dans Bash sont généralement minuscules (ou toutes les capuchons pour les variables d'environnement) et non sur un boîtier de chameau. Il n'y a pas besoin de sortie 0 à la fin ( echo aura retourné 0 anayway).


Camelcase fait simplement des choses faciles à lire et est une habitude de la mienne, je suppose que cela ne briserait rien ... Mais merci pour les autres conseils, je commence vraiment à aimer la communauté ici. :RÉ


Yup, camelcase va bien; Le seul endroit où les mauvais nom de variables conduisent à des bugs utilisent toutes les choses qui ne sont pas des variables d'environnement ou des intégrées (comme cela conduit à des conflits avec des variables qui sont dans l'une de ces classes).


3 Réponses :


5
votes

Essayez quelque chose comme xxx pré>

et voyez ce qui se passe. p>

EDIT: Ajout de la tête * à chaque chemin comme dans votre exemple. P>

Et voici une solution complète basée sur votre description. P>

#!/usr/bin/env bash
basepath="/home/adesso/baldar"
ignore=("/cgi-bin" "/tmp" "/test" "/html" "/icons")

find "${basepath}" -maxdepth 1 -not \( -path "*${ignore[0]}" $(printf -- '-o -path "*%s" ' "${ignore[@]:1}") \) -not -path "${basepath}" -type d


5 commentaires

J'ai donc fini par envoi de votre code dans une substitution de commande et l'attribuez à une variable, mais j'aimerais qu'il s'agisse d'une matrice afin que je puisse faire boucler les valeurs et faire ma sauvegarde par répertoire. sous-domaines = $ (trouver $ {basepath} / * -maxdepth 0-Not \ (-Path "* * $ {iggy [0]}" $ (printf - '-O -Path "*% s"' " $ {Iggy [@]: 1} ") \) -type d) Je n'arrive pas à trouver la signification de la - vous utilisez dans Printf ?? Désolé pour le camelcase


Essayez printf '-o' par lui-même et vous verrez ce que ça fait. Pour transformer les résultats de cette retrouver dans un tableau, je recommande une petite substitution de commande et un moment LIRE, E.G. pendant que ifs = lisez -r fichier; faire ... fait << (TROUVEZ ...)


Cela ressemble beaucoup aux problèmes si la liste Ignorer contient des chaînes avec des citations littérales, des espaces, etc. beaucoup plus sûrs pour construire les chaînes dans une matrice unique cotée, plutôt que d'utiliser la substitution de commande Pour générer une chaîne, String-Split-Split and Glob s'est développé.


@Sorpigal, j'essaie de faire ce qui suit, mais cela ne fonctionne pas - il semble ignorer le premier élément de la liste que j'ai créée. Y a-t-il quelque chose qui ne va pas dans la façon dont j'ai peuplé la liste? #! / bin / bash ignore = () pendant que ifs = lecture -r -d $ '\ n'; TO IGNORE + = ("/ $ RÉPONSE") effectué << (Recherche! -Path. -TYPE D -PRINTF '% T @% P \ N' | Trier -nr | Tête -n $ 1 | AWK '{IMPRESS $ 2}' && ReadLink Current)


@walksignison: Adressage trop compliqué à faire ici. Vous pouvez créer une nouvelle question ou venir à ## Linux sur irc.freenode.net et demander à nouveau.



0
votes
FIND="$(which find --skip-alias)"
BasePath="/home/adesso/baldar"
Iggy=( "/cgi-bin" 
    "/tmp" 
    "/test" 
    "/html" 
    "/icons" )
SubDomains=( $(${FIND} ${BasePath}/* -maxdepth 0 -not \( -path "*${Iggy[0]}" $(printf -- '-o -path "*%s" ' "${Iggy[@]:1}") \) -type d) )
echo ${SubDomains[1]}
Thanks to @Sorpigal I have a solution. I ended up nesting the command substitution so I can use the script in a cron, and finally added the Array definition around all of it. A known problem would be a directory containing a space in the name. This however has been solved, so trying to keep it simple, I think this answers my question.

0 commentaires

2
votes

Les réponses existantes sont buggy lorsque des noms de répertoire donnés contiennent des espaces littéraux. La pratique sûre et robuste est d'utiliser une boucle. Si votre préoccupation consiste à tirer parti de «la puissance de bash» - je dirais qu'une solution robuste est plus puissante qu'un buggy un. :) xxx


5 commentaires

Le point était ne pas utiliser une boucle . Je pense qu'il y a suffisamment d'exemples de la boucle et de prendre soin des espaces et des citations, ce n'était pas le point. SIMPLICITY était. Les bugs sont des fonctionnalités. J'essayais de saisir la puissance de Bash Basic . - Mais maintenant, tu m'as commencé à nouveau, alors j'essaie de voir si je peux résoudre cet espace et citations problème sans boucles;)


Dans de nombreux cas similaires, l'utilisation intelligente des opérateurs d'expansion des paramètres fera l'affaire (préparé ou suffixant chaque élément de tableau, par exemple). Je ne sais pas si l'une de ces astuces s'applique ici, cependant. Et oui, je comprends ce que vous demandiez - mais j'ai une réaction viscérale quelque peu forte à toute question où la réponse «correcte» est le code que personne ne devrait jamais utiliser dans un système de production. Si vous avez trouvé une réponse non en boucle SAFE , cela aurait certainement mon vote.


@ Willemp.botha, ... je modifierai effectivement cela pour éviter la boucle; Bien que ce soit un horrible piratage horrible, printf '% q' fait fait ce soin de sécurité.


J'ai une allergie d'évaluation ... mais ça a l'air légitime


Je partage cette allergie. Voir aussi "Hack horrible terrible".