2010-10-05 5 views
2

Je suis en train de lire un fichier de propriétés qui contient des chemins de fichier utilisant un script shell. Maintenant, en fonction de ce chemin de fichier, je veux créer le nom du fichier zip. Quelque chose comme ça ... Mon propriété contenu du fichier ::Comment créer le nom de fichier requis dans unix à l'aide du script shell

path=tmp/inputs/logs/abc 
path=tmp/backup/inte/xyz 
destpath=abc/xyz 

Maintenant, je suis en mesure de créer le nom de fichier comme abc.zip et xyz.zip comme:

paths=`grep path myfile.property |cut -d= -f2` 
d_path=`grep destpath myfile.property |cut -d= -f2`  
filename=$d_path/$(basename $paths).zip 

qui créent abc.zip et xyz.zip. Mais je veux créer un nom en prenant les trois derniers paramètres du chemin. Quelque chose comme ça ...

  • pour abc.zip il devrait être inputs_logs_abc.zip et
  • pour xyz.zip il devrait être backup_inte_xyz.zip

EDIT

Paths=`grep path myfile.txt |cut -d= -f2` 

d_Path=`grep destpath myfile.txt |cut -d= -f2` 

for s_Path in $Paths 

    do 

     prefix=${Paths%%/*/*/*}  
     without_prefix=${Paths##${prefix}/} 
     slashes_to_underscores=${without_prefix//\//_} 
     zipFile=$d_Path/${slashes_to_underscores}.zip 
     find $s_Path -type f -name "*.log" | xargs zip -mT $zipFile [email protected] 

    done 

Au-dessus est mon code.By En utilisant ce que je ne suis pas capable d'atteindre ma cible. Quelqu'un peut-il m'aider dans ce domaine?

+0

Quel shell écrivez-vous? Quelle est la pertinence de 'destpath' et' d_path' dans ces snippets? – Johnsyweb

+0

J'utilise bash.destpath est un mot-clé qui se trouve dans le fichier de propriétés, d'après lequel je lis ce fichier et stocke ce chemin dans la variable d_path. – MAS1

+0

Alors ma réponse devrait résoudre votre problème. Vous pouvez l'essayer à l'invite et faire écho aux variables au fur et à mesure pour voir comment cela fonctionne. – Johnsyweb

Répondre

3

Étant donné que vous utilisez bash (cela s'applique également à zsh ou similaire), vous pouvez utiliser sa substitution de paramètre intégrée.

% path=tmp/inputs/logs/abc 
% prefix=${path%%/*/*/*} 
% without_prefix=${path##${prefix}/} 
% slashes_to_underscores=${without_prefix//\//_} 
% filename=${slashes_to_underscores}.zip   
% echo $filename   
inputs_logs_abc.zip 

Vous pouvez préfixer ${d_path} selon le cas à ${filename}. $path dans mon exemple est codé en dur, vous l'affecter dans une boucle sur ${paths}, comme fahd's answer à your previous question.

  • ${var//exp/sub} remplace toutes les instances de exp à $var avec sub
  • ${var%%exp} trims une instance de exp du droit de var
  • ${var##exp} garnitures toute instance de exp de la gauche de var

Modifier (après un peu de sommeil et de clarification):

prefix=${path%%/*/*/*}greedy correspond de droite à gauche. Si vous avez un '/' avant tmp cela va casser (ce n'est pas ce que vous avez dit que vous faisiez dans votre commentaire, mais donnerait ce résultat). Changez cette ligne pour qu'elle soit prefix=${path%/*/*/*} (signe de pourcentage unique: non gourmand) et ceci devrait corriger les chemins plus longs et plus courts.

Edit 2 (mise à jour suivante à la question):

Je vois trois problèmes:

  1. "Chemins = grep path myfile.txt |cut -d= -f2" # Ceci correspond à "DestPath = abc/xyz", vous devriez probablement grep pour '^path=' pour obtenir seulement les lignes qui commencent par "path =".
  2. Vous utilisez ${Paths} deux fois dans la boucle où vous devriez utiliser (curieusement) ${s_Path}. Vous utilisez toujours le match glouton dans la ligne prefix=. Voir mon édition précédente.
+0

@ Johnsyweb, merci pour votre réponse. Mais ci-dessus le nom du fichier cretae de code avec le chemin complet, signifie que si le chemin est chemin = tmp/xyz/inputs/logs/abc alors il crée le nom de fichier comme tmp_xyz_inputs_logs_abc.zip. Mais je veux seulement trois derniers noms de répertoires comme inputs_logs_abc.zip. – MAS1

+0

J'utilise votre code en boucle (réponse de fahd) qui est présent dans ma question précédente. – MAS1

+0

Le code de mon exemple a été copié directement à partir de la ligne de commande. 'path = tmp/inputs/logs/abc' est l'entrée et' inputs_logs_abc.zip' est la sortie comme démontré. Veuillez ajouter le code complet que vous avez maintenant en tant que modification à votre question afin que je puisse voir où le bogue est. – Johnsyweb

0

Est-ce que cela fonctionne pour vous?

paths=$(grep path myfile.property |cut -d= -f2) 
d_path=$(grep destpath myfile.property |cut -d= -f2) 
extname=$(echo $paths | sed 's%^.*/\([^/]*/[^/]*/[^/]*\)$%\1%;s%/%_%g') 
filename=$d_path/$extname.zip 

Le premier substitut dans le script sed enlève maintenant tout avant les trois derniers éléments du chemin - ne pas enlever quoi que ce soit, s'il n'y a que deux - et la seconde mappe les barres obliques qui restent à underscores. Notez que vous aurez des problèmes si les chemins ont des barres obliques (même si vous pouvez ajouter un substitut pour les supprimer). Vous obtiendrez également un trait de soulignement principal dans le nom s'il contient, par exemple, /tmp/pattern. Vous devrez peut-être vous préoccuper de l'utilisation de '[^/][^/]*' à la place de '[^/]*' pour vous assurer qu'il n'y a pas de noms de composants vides (et vous pourriez aussi vous inquiéter des barres obliques doubles). Et GNU Sed vous fournit des fonctionnalités regex supplémentaires afin que vous puissiez utiliser '[^/]+' à la place.

+0

Merci pour la réponse ... mais le chemin que j'ai donné ici sont tous juste des exemples..ainsi nous ne pouvons prédire aucun mot-clé dans le chemin. Cependant les mots-clés path et d_path dans le fichier de propriétés sont finaux. – MAS1