Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/01/2011, 23h15   #1
Membre du Club
 
Inscription : septembre 2006
Messages : 339
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 339
Points : 47
Points : 47
Par défaut "Cat" est trop lent (Windows)

Bonjour,

je suis en train d'executer une simple commande de concatenation de fichier:
Code :
1
2
3
4
for file in `ls *.logic`
    do
        cat $file >> final.logic
    done
Ce code la prend exactement 5 secondes sur une machine Linux, 1min15 sur une machine Windows XP (RAM 3.5G), et 3min30 sur une machine Windows 7 (bien que plus puissante: RAM 8G)

J'ai essaye de remplacer la commande cat par : type, ou awk mais j'ai toujours pratiquement les meme temps d'execution.

Je n'ai rien trouve sur le net qui explique la difference qui peut y avoir entre l'utilisation de cat dans des SE differents.

Qqn a une idee SVP?
ou au moins une solution pour avoir une performance quasi egale entre Linux et windows?

Merci
freestyler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2011, 23h44   #2
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 069
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 069
Points : 4 145
Points : 4 145
pourquoi faire une boucle, qui lancera autant de cat qu'il y a de fichiers ?

le but de cat est justement de concaténer le contenu de fichers, donc :
Code :
cat *.logic >> final.logic
et puis, on ne fait pas for item in $(command); surtout pas ls. parce que
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/01/2011, 12h05   #3
Expert Confirmé Sénior
 
Avatar de frp31
 
Homme francois
Ingénieur systèmes et réseaux
Inscription : juillet 2006
Messages : 3 534
Détails du profil
Informations personnelles :
Nom : Homme francois
Âge : 35
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur systèmes et réseaux
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : juillet 2006
Messages : 3 534
Points : 7 743
Points : 7 743
Citation:
Envoyé par freestyler Voir le message
Bonjour,

Ce code la prend exactement 5 secondes sur une machine Linux, 1min15 sur une machine Windows XP (RAM 3.5G), et 3min30 sur une machine Windows 7 (bien que plus puissante: RAM 8G)

Merci
plus puisssant pas vraiment
pour info la ram ne represente que la quantité de données qui peut y etre stockée sans avoir a faire des copies depuis/vers le disque qui est un périphérique mécanique et par concequent lent.

deplus 8G de ram lente freinera plus le ressenti que 4 ou meme 2 rapide

La quantité de ram n'accelere que tres tres tres peu le ressenti utilisateur.
la comparaisent en seconde est pertinante mais pas la suite de la phrase

Pour le reste j'allais faire la meme remarque que N_BaH, qui a tout a fait raison
frp31 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 14h22   #4
Membre du Club
 
Inscription : septembre 2006
Messages : 339
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 339
Points : 47
Points : 47
En fait j'essayais de reduire la question a l'essentiel..
En fait voici mon code:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        for file in `ls *.logic`
        do
 
            tmp_ext=`grep $(basename $file) list.external`
            if [[ ! -z $tmp_ext ]]; then  
                cat $file >> external.logic
                echo >> external.logic
            else            
                tmp_exc=`grep $(basename $file) list.exclude`
                if [[ -z $tmp_exc ]]; then
                    cat $file >> final.logic
                    echo >> final.logic
                fi
            fi
        done
Ceci explique l'usage de la boucle..

Par contre, aucun d'entre vous n'a souleve le probleme de la difference des temps d'execution entre SE, qui est la source meme du probleme..
freestyler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 21h19   #5
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 069
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 069
Points : 4 145
Points : 4 145
Citation:
Par contre, aucun d'entre vous n'a souleve le probleme de la difference des temps d'execution entre SE, qui est la source meme du probleme..
Désolé, je n'utilise pas Windows.
Code bash :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        for file in `ls *.logic`
        for file in *.logic
        do
            tmp_ext=`grep $(basename $file) list.external`
            if [[ ! -z $tmp_ext ]] #ah, bah, non alors ! pas une double négation !
            #if [[ -n $tmp_ext ]]
            if grep "${file##*/}" list.external >/dev/null 2>&1
            then  
                cat "$file" - >> external.logic
                echo >> external.logic
               extFiles+=( "$file" )
            else            
# la condition opposée est implicite avec le else
                tmp_exc=`grep $(basename $file) list.exclude`
                if [[ -z $tmp_exc ]]; then
                    cat "$file" - >> final.logic
                    echo >> final.logic
                fi
                finalFiles+=( "$file" )
            fi
        done
cat "${extFiles[@]}" >> external.logic
cat "${finalFiles[@]}" >> final.logic
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 26/01/2011, 16h38   #6
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
j'adore les réponses de N_BaH

sinon, pour les problèmes de temps de réponse (qui ne sont pas forcément à l'origine du problème), tu utilises quoi sous Windows ? Cygwin ou les versions Windows des coreutils ?
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2011, 17h58   #7
Membre du Club
 
Inscription : septembre 2006
Messages : 339
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 339
Points : 47
Points : 47
Cygwin.

J'ai aussi essayé d'utiliser Windows Coreutils seulement mais j'ai toujours eu les mêmes problèmes..
freestyler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2011, 21h22   #8
Membre du Club
 
Inscription : septembre 2006
Messages : 339
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 339
Points : 47
Points : 47
Quelqu'un a-t-il fait le test au moins?

Ca me semble pourtant un post valide parce que les écarts entre Linux et Windows sont énormes. Et encore, meme entre Win7 et WinXP.

J'ai beau cherché sur le net mais je n'ai trouvé aucune information sur le sujet..
freestyler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 14h15   #9
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
Quelle volumétrie tu as ?

Je viens de faire un test sur un bête PC sous Windows XP (X2 2GHz avec 2Go de RAM) sur 152 Mo et 284 fichiers .txt et ça prend genre 5 secondes; sur 840 Mo et 19 fichiers .dsx (c'est comme des fichiers textes), ça a pris 40 secondes...

Les tests :
Code :
1
2
d:\temp\>cat *.txt >> test001
d:\temp\>cat *.dsx >> test002
Les temps sont mesurés à la mimine mais bon, ça me paraît pas énorme comme temps...

Donc à mon avis, soit c'est le reste de ton algo qui faisait perdre du temps, soit c'est cygwin quand tu utilises cygwin... dans tous les cas, difficile de répondre vu qu'il manque pleins d'informations (en vrac) :
le test sous Linux, tu l'as fait sur la même machine ? Parce que tu parles de la RAM, mais pour cat seul, on s'en fiche : pour info, lors de mon test, cat a pris mois de 2 Mo de RAM ! Par contre, si tu as un disque en 10k rpm en raid 0 sous Linux et un vieux disque pata sous Windows, ça va plus jouer !
ton disque Windows n'est pas fragmenté ?
quelle est exactement la commande que tu compares : le script complet ou juste le cat ? Avec ou sans la boucle for ? etc...
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 27/02/2011, 02h14   #10
Membre du Club
 
Inscription : septembre 2006
Messages : 339
Détails du profil
Informations forums :
Inscription : septembre 2006
Messages : 339
Points : 47
Points : 47
Bon après de multiples tests, il s'est avéré que le temps varie à cause de l'usage de la boucle for pour cat.

Donc, capturer la liste dans une variable et faire : réduit le temps d'exécution d'une manière très évidente.

Par contre, cela me fait revenir au problème initial auquel j'ai du écrire une boucle pour : c'est la nécessite d'ajouter unes ligne vide à la fin de chaque fichier pour avoir une concaténation acceptable.
Si fichierA ne contient pas de retour chariot à la fin, alors la dernière ligne de fichierA et la première ligne de fichierB seraient sur la même ligne si on fait:
Y a aucune option de cat qui fait ceci.
Et j'ai beau cherché… une boucle s'impose ici. Ya t il une alternative?

Merci beaucoup
freestyler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/02/2011, 07h48   #11
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 069
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 069
Points : 4 145
Points : 4 145
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

for file in *.logic
do if grep "${file##*/}" list.external >/dev/null 2>&1
   then extFiles+=( "$file" )
   else finalFiles+=( "$file" )
   fi
#si la dernière ligne du fichier ne se termine pas par \n, on en ajoute un.
   [[ $(od -c <(tail -1 "$file")) == *\n ]] || printf $'\n' >> "$file"
done

cat "${extFiles[@]}" >> external.logic
cat "${finalFiles[@]}" >> final.logic
...
?
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 27/02/2011, 09h45   #12
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Peut être une alternative avec "sed" :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cat A
azerty
qsdfg
wxcvb$     # Pas de retour à la ligne ici
$ cat B
poiuy
mlkjh
nbvcx
$ cat A B
azerty
qsdfg
wxcvbpoiuy     # Pas de séparation
mlkjh
nbvcx
$ sed -n '/./p' A B
azerty
qsdfg
wxcvb
poiuy
mlkjh
nbvcx
$


Édit : Suffit amplement
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 20
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h26.


 
 
 
 
Partenaires

Hébergement Web