Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

#1 Le 19/02/2010, à 14:53

flagelux

[résolu][Bash] récupérer la valeur d'une astérisque

Bonjour,

dans un script bash je souhaite concaténer plusieurs groupes de fichiers. Pour chaque groupe je souhaite récupérer la partie commune du nom de fichier pour qu'elle figure dans le fichier résultant. Exemple :

j'ai, disons, ces fichiers :

toto1-zefzfefzf.drf.01
toto1-zefzfefzf.drf.02
toto1-zefzfefzf.drf.03
toto1-zefzfefzf.drf.04   ...

toto2-sdvlnsdv.drf.01
toto2-sdvlnsdv.drf.02
toto2-sdvlnsdv.drf.03
toto2-sdvlnsdv.drf.04
toto2-sdvlnsdv.drf.05 ...

toto3-pnponds.drf.01 ...

etc, disons qu'il y en a plein genre (toto3712.posdvn.drf) et pour simplifier on va dire qu'il n'y en a pas plus de 9 par groupe.


je souhaite les concaténer en toto1-zefzfefzf.drf, toto2-sdvlnsdv.drf, toto3-pnponds.drf et ainsi de suite.

De plus, on va dire que la partie du nom de fichier situé entre le trait d'union et le point (soit zefzfefzf pour le premier lot) m'est inconnue (plus précisément je n'ai pas envie de la retrouver à la main pour chaque fichier)

j'ai donc pondu naïvement ce script:

#!/bin/bash
for ((a=1; a <= 3712 ; a++))
do
cat toto$a-*.drf.0* > toto$a-*.drf
done

Et bien entendu cet imbécile de bash me pond les fichiers suivant :

toto1-*.drf
toto2-*.drf
toto3-*.drf
...
toto3712-*.drf

Donc ma question est : comment faire pour récupérer/capturer ce que je remplace par une astérisque * dans la partie gauche de mon cat pour le réinjecter dans la partie droite (celle du fichier résultant)?

Merci de vos réponses

Dernière modification par flagelux (Le 20/02/2010, à 02:06)

Hors ligne

#2 Le 19/02/2010, à 15:59

AnsuzPeorth

Re : [résolu][Bash] récupérer la valeur d'une astérisque

flagelux a écrit :

Et bien entendu cet imbécile de bash me pond les fichiers suivant :

Tu es certain que c'est bash l'imbécile ??? wink

Blagues à part.

Tu pourrais t'y prendre autrement, récupérer le pattern commun aux fichiers, si égalité, copier dans le fichier destination:
un truc du genre: (ce n'est pas fonctionnel, c'est pour exemple)

cd /home/dossier
old_nom_fichier=
for fichier in *drf*
do
  nom_fichier=récupe nom fichier (voir substitution bash pour supprimer indice)
    if $nom_fichier = $old_nom_fichier; then
         cat $fichier >> $old_nom_fichier
    else
         cat $fichier >> $nom_fichier
    fi
old_nom_fichier=$nom_fichier

done

C'est une possibilité, il y en a d'autres, bien sur !

Dernière modification par AnsuzPeorth (Le 19/02/2010, à 16:01)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#3 Le 19/02/2010, à 17:18

credenhill

Re : [résolu][Bash] récupérer la valeur d'une astérisque

hello

#!/bin/bash

for ((a=1;a<=3712;a++));do
NOM=$(ls toto${a}*.drf.*|sed 's/\.0[0-9]*$//;q')
cat toto${a}*.drf.* > $NOM
done

Hors ligne

#4 Le 19/02/2010, à 18:17

flagelux

Re : [résolu][Bash] récupérer la valeur d'une astérisque

Merci à vous deux pour votre aide.

Je n'ai pas compris ta démarche AnsuzPeorth, désolé.

La soluce de credenhill me convient, je vais essayer de l'adapter en échappant les éventuelles espaces dans les noms de fichiers.

Encore merci du coup de main.

Hors ligne

#5 Le 19/02/2010, à 18:54

AnsuzPeorth

Re : [résolu][Bash] récupérer la valeur d'une astérisque

flagelux a écrit :

Je n'ai pas compris ta démarche AnsuzPeorth, désolé.

C'est pourtant la base ... smile (tu devrais y regarder de plus pret !)

cd /home/dossier
old_nom_fichier=
for fichier in *drf* #pour chaque fichier trouvé avec drf dans son nom, fichier=nom complet du fichier
do
 #nom_fichier sera égale à 'toto1-zefzfefzf.drf', on supprime l'indice 01. 02. 03 ....
  nom_fichier=${fichier%.*}
    # si ce nom correspond à old_fichier (le premier tour, old_nom_fichier=" ", le tour suivant old_nom_fichier='toto1-zefzfefzf.drf', affectation plus bas.
    # premier tour (donc premier fichier trouvé par for)
    # nom_fichier=toto1-zefzfefzf.drf; old_nom_fichier=" "
    # deuxieme tour nom_fichier=toto1-zefzfefzf.drf; old_nom_fichier=toto1-zefzfefzf.drf
    # dixième tour (9 fichiers par groupe tu as dit) nom_fichier=toto2-sdvlnsdv.drf; old_nom_fichier=toto1-zefzfefzf.drf
    # onzieme tour  nom_fichier=toto2-sdvlnsdv.drf; old_nom_fichier=toto2-sdvlnsdv.drf
    # etc, etc
if [ "$nom_fichier" = "$old_nom_fichier" ]; then
         cat "$fichier" >> "$old_nom_fichier"
    else
         cat "$fichier" >> "$nom_fichier"
    fi
#on affecte le nom_fichier à old_nom_fichier, pour comparaison  avec le fichier suivant
old_nom_fichier=$nom_fichier
done

en plus condensé

cd /home/dossier
old_nom_fichier=
for fichier in *drf* ; do
   nom_fichier=${fichier%.*}
  [ "$nom_fichier" = "$old_nom_fichier" ] && fichier_sortie=$old_nom_fichier || fichier_sortie=$nom_fichier
  cat "$fichier" >> "$fichier_sortie"
   old_nom_fichier=$nom_fichier
done
flagelux a écrit :

La soluce de credenhill me convient, je vais essayer de l'adapter en échappant les éventuelles espaces dans les noms de fichiers.

Pourquoi pas, une remarque qd même, sa solution va lancer 3712 la commande ls | sed (avec une ER en prime pour sed), niveau ressource et rapidité, ca va pas être ça .... !
Ma solution ne fait que comparer des variables, une petite substitution bash et c'est tout (un cat bien sur wink). Le nombre de fichiers n'est pas limité .

EDIT:
Ou alors, un truc du genre (pas testé)

ls | awk -F '.' '{print $1 "." $2}' | sort -u | while read ligne
do
cat $ligne* > $ligne
done

Dernière modification par AnsuzPeorth (Le 19/02/2010, à 19:21)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#6 Le 20/02/2010, à 02:01

flagelux

Re : [résolu][Bash] récupérer la valeur d'une astérisque

Effectivement c'était pas la mer à boire, et du point vue complexité c'est bien meilleur.

En ce qui concerne awk, que je ne connais presque pas, mais aprés quelques recherches j'ai réussi à me dépatouiller de cette commande, ça a l'avantage de la concision. Trés pratique aussi le paramètre -u de la commande sort.

Merci de m'avoir, comme un tapis rouge, déroulé la boucle!

Hors ligne

#7 Le 20/02/2010, à 11:21

nesthib

Re : [résolu][Bash] récupérer la valeur d'une astérisque

pour récupérer le nom de fichier commun :

VARIABLE="toto1-zefzfefzf.drf.01"
echo ${VARIABLE%.*}

supprimera le point et l'indice du fichier, à insérer dans une boucle, je te laisse faire

edit : lu un peu vite, c'est ce qu'a fait AnsuzPeorth…

Dernière modification par nesthib (Le 20/02/2010, à 11:22)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdnGMT-4

Hors ligne

#8 Le 20/02/2010, à 22:24

flagelux

Re : [résolu][Bash] récupérer la valeur d'une astérisque

En effet, mais merci quand même nesthib.

A noter au passage le comportement greedy par défault de la chose qui va aller chercher le dernier point comme d'ailleurs dans le code awk de AnsuzPeorth.

Hors ligne

#9 Le 20/02/2010, à 22:31

nesthib

Re : [résolu][Bash] récupérer la valeur d'une astérisque

la syntaxe ${variable%regexp} élimine la regexp la plus courte qui corresponde. Pour la plus longue : ${variable%%regexp} pour éliminer après l'avant dernier point : ${variable%.*.*}


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdnGMT-4

Hors ligne

#10 Le 21/02/2010, à 03:23

AnsuzPeorth

Re : [résolu][Bash] récupérer la valeur d'une astérisque

Re,
A la place de la boucle, on aurait aussi pu envoyer à xargs. (syntaxe un peu plus tordu, j'utilise seulement si beaucoup de fichier à traiter, pour raccourcir le temps de traitement)

ls *drf* | awk -F '.' '{print $1 "." $2}' | sort -u | xargs -I{} bash -c "cat "{}*" > "{}""

Pour compléter les dires à netshib

:~$ VARIABLE="toto1-zefzfefzf.drf.01"
:~$ echo ${VARIABLE%.*}
toto1-zefzfefzf.drf
:~$ echo ${VARIABLE%%.*}
toto1-zefzfefzf
:~$ echo ${VARIABLE#*.}
drf.01
:~$ echo ${VARIABLE##*.}
01

Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#11 Le 22/02/2010, à 19:33

sputnick

Re : [résolu][Bash] récupérer la valeur d'une astérisque

nesthib a écrit :

la syntaxe ${variable%regexp} élimine la regexp la plus courte qui corresponde. Pour la plus longue : ${variable%%regexp} pour éliminer après l'avant dernier point : ${variable%.*.*}

Ouhla malheureux ^^ Ce n'est pas une regexp mais un glob, c'est une "nuance" qui a son importance wink


bashfr.org(random);
<arciks1994> dou tu connai qel age j'ai ?

Hors ligne

#12 Le 22/02/2010, à 19:49

sputnick

Re : [résolu][Bash] récupérer la valeur d'une astérisque

printf '%s\n' * | cut -d'-' -f1 | sort -u | xargs -I% bash -c "cat %* > %.drf"

bashfr.org(random);
<arciks1994> dou tu connai qel age j'ai ?

Hors ligne

#13 Le 22/02/2010, à 20:14

nesthib

Re : [résolu][Bash] récupérer la valeur d'une astérisque

sputnick a écrit :

Ouhla malheureux ^^ Ce n'est pas une regexp mais un glob, c'est une "nuance" qui a son importance wink

c'est vrai, la syntaxe est différente, abus de langage de ma part wink (le principe reste le même)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdnGMT-4

Hors ligne

Haut de page ↑