Sed : Argument list too long [Résolu/Fermé]

Signaler
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
-
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
-
Salut,
Et voilà je continue à galèrer. :p
Cette fois c'est la commande sed, qui m'empêche de faire ce que je veux. (encore des limitations)
Je veux lancer une commande qui touche un peu trop de fichiers semble-t-il :
sed -i 's#bateau #maison #' ../*/*/*/*

Mais bon je ne peux pas faire autrement. :D

Lors du lancement je reçois un message d'erreur :
bash: /bin/sed: Liste d'arguments trop longue


J'ai vu une histoire de "find" ou "xargs" mais bon je n'y arrive pas.
Si quelqu'un a une solution. :)
Thx.. ou mono
A voir également:

34 réponses

Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Pour la phrase "10 dernières lignes avant les 10 dernières" :
Il se trouve que le mot bateau se trouve toujours à cet endroit dans le fichier. (Si le fichier fait 30 lignes, le mot sera entre la ligne 10 et la ligne 20, si le fichier fait 3000 lignes, le mot sera entre la ligne 2980 et la ligne 2990 etc...)

Mon problème est évidemment le suivant : Mes commandes sont beaucoup trop lourdes. :)
Elles viennent de tourner pendant 19 heures là, et ça n'a pas beaucoup avancé. :p

Comme solutions j'ai pensé à :

1-Limiter la recherche du motif "bateau" uniquement aux 10 dernières lignes avant les 10 dernières.
2-Arrêter la recherche du motif "bateau" quand il a été trouvé une fois dans chaque dossier situé dans ../ (le ../ que j'utilise dans la commande "find ../ -type f -name "*.txt" -exec sed -i 's#bateau#maison #' {} \;" (donc 25 fois maximum)
3-Le motif "bateau" n'apparait qu'une seule fois par fichier, alors il ne sert à rien de continuer à rechercher le motif dans le même fichier une fois qu'il a été trouvé. (Enfin celui là ne risque pas de raccourcir énormément le temps d'execution vu que le motif est à la fin du fichier)

Voilou en gros mes idées. Mais pour les mettre en pratique c'est une autre paire de manche.
Si vous avez d'autres idées, ce n'est que mieux. :p

(Je vais étudier un peu grep et find, d'après ce que je vois elle peuvent être très intéressantes)
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
[cite]tu ne veux toujours pas m'afficher le résultat.

Les voici :

find ../ -type f -name "*.txt" | wc -l
34 148

find . -name '*.txt' -exec grep -c bateau {} \;|awk '{SUM += $1}END{print SUM}'
1

find ../ -name '*.txt' -exec grep -c bateau {} \;|awk '{SUM += $1}END{print SUM}'
25


[cite]tree -P "*.txt" -o log
Contient des informations que je ne peux pas mettre sur internet. :(
Si c'est indispensable je pourrais modifier mon programme pour générer quelque chose de factice.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 532
Salut,

Ben, je ne comprends pas.
Tu as seulement 25 remplacements à faire et pour ça tu penses à une année de calcul?!
Je ne crois pas.

Mes commandes sont beaucoup trop lourdes. :)
Quelles commandes.
D'après ce que j'ai compris il n'y a qu'une commande.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 532
Re,

Sinon, pour s'arrêter après avoir trouver une correspondance regarde ici
http://www.commentcamarche.net/forum/affich 12129690 grep sur fichier volumineux
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
J'ai 50 000 commandes dans un fichier SH. (temps d'execution équivalente puisque qu'elles parcourent tout :p)
L'une d'entre elle met 15 minutes à se terminer.
50 000 * 15 = 750 000 (minutes)
750 000 / 60 = 12 500 (heures)
12 500 / 24 = 520 (jours)
520 / 365 = 1.42 (année)

Depuis la découverte de sed, celui-ci m'a bien rendu service, mais là je pense que je vais peut être devoir faire un système de recherche de motif par moi même.
Messages postés
40805
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 851
J'ai 50 000 commandes dans un fichier SH.
Waouw ;-\

Et tu ne peux pas faire exécuter certaines commandes en parallèle ?
Scinder ton fichier en plusieurs parties ?
Faire des regroupements de commandes ?
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
:D

Et tu ne peux pas faire exécuter certaines commandes en parallèle ?
Je dois modifier par exemple "bateau1" par "maison" et "bateau2" par "oiseau", possible de regrouper ça dans une seule commande ?
(Du style rechercher le motif "bateau" et ensuite implémenter un if dans le sed : si 1 après bateau remplacer par maison, si 2 après bateau remplacer par oiseau etc ..) Possible ?

Scinder ton fichier en plusieurs parties ?
Euh je peux tenter de faire quelque chose qui extrait les 10 dernières lignes avant les 10 dernières lignes du fichier et les mettre dans d'autres fichiers. (et ce sont eux que je devrais modifier) Et ensuite les réinjecter dans le fichier d'origine mais euuuuhh ça m'a l'air complexe. :D

Faire des regroupements de commandes ?
Euh.
Messages postés
40805
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 851
Euh... on doit mal se comprendre là ;-\

"50000 commandes dans un fichier" = Ton fichier (script) contient bien 50000 commandes ?

Donc ces commandes tu peux les utiliser séquentiellement (les unes à la suite des autres, chacune attendant la fin de la commande précédente pour de lancer) ou en parallèle (lancer en arrière-plan avec "&", les commandes s'exécutant dans un shell fils quasiment en même temps (en partageant le temps plus exactement)).
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Ouaip 50 000 lignes du type :
sed -i 's/bateau1/maison/' *
sed -i 's/bateau2/oiseau/' *

etc ...

En remplacant cela par
sed -i 's/bateau1/maison/' * & sed -i 's/bateau2/oiseau/' *

Vous pensez que cela peut améliorer les performances ?

En fait je pensais que c'était exactement pareil mais en une seule ligne. :)
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 532
Re,

Je dois modifier par exemple "bateau1" par "maison" et "bateau2" par "oiseau", possible de regrouper ça dans une seule commande ?

Tiens, on doit se casser un peut la tête pour que tu commencer à "cracher" ce que tu veux faire.

Si tu pourras expliquer avec plus de précisions, je pourrais peut être penser à une solution en Perl.
Tant que tu ne peux pas faire ça, je suis désolé.

J'ai 50 000 commandes dans un fichier SH.
Tu as 50 000 motifs à remplacer?!
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 532
Re,

Tu peux mettre dans un fichier .txt le motif à remplacer avec le remplaçant correspondant

motif;remplaçant

Ensuite avec une seule commande pour chaque motif de fichier faire le remplacement correspondant
Messages postés
40805
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 851
Euh... non ;-(

Soit :
sed -i 's/bateau1/maison/;s/bateau2/oiseau/' *
Soit tu mets toutes tes commandes dans un fichier texte (script.sed par exemple) :
s/bateau1/maison/
s/bateau2/oiseau/
etc.
s/bateau3/moineau/
etc.
Que tu appelles ensuite :
sed -i -f script.sed *
;-))
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 532
Re,

Dans un de mes messages j'ai dit

Ici on parle d'une commande.
Ton programme contient autre chose?!


Maintenant tu dis que tu as 50 000 commandes.
Ben, on n'est pas devant ton pc pour voir ce que ton script contient.
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Je dois modifier par exemple "bateau1" par "maison" et "bateau2" par "oiseau", possible de regrouper ça dans une seule commande ?
Ce n'est qu'un exemple, le contexte est trop aléatoire pour en faire une règle universelle. J'essai juste de trouver une manière de gagner du temps. (Si jamais ce phénomène a lieu)

Tu as 50 000 motifs à remplacer?!
Oui, sinon je n'aurais pas 50 000 commandes. :)

Bon, je vous remercie de votre enthousiasme pour m'aider. Mais cette fois je pense que sed ne me sauvera pas. (Il a déjà tant fait pour moi lol il ne faut pas trop en demander)

Je retourne faire du codage pour résoudre ce problème. (Que j'aurai pu anticiper...)
Je vais tenter de résoudre ce problème à la source. :D (Les fichiers txt sont générés par mon programme)
"find /chemin/complet -type f -exec sed -i 's#bateau #maison #' {} \;" va bien me servir. ;)

Je reviendrai pleurer sur le forum si vraiment je n'arrive à rien. Ca fait plaisir de voir des gens qui se mettent en 4 pour résoudre des problèmes qui ne sont pas les leurs.
Merci encore !!