Sed : Argument list too long

Résolu/Fermé
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 - 1 mai 2009 à 03:45
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 - 3 mai 2009 à 17:46
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

bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 16:06
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)
0
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 16:23
[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.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 mai 2009 à 16:26
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.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 mai 2009 à 16:32
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 16:38
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.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 mai 2009 à 16:51
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 ?
0
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 17:04
: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.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 mai 2009 à 17:16
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)).
0
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 17:26
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. :)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 mai 2009 à 17:28
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?!
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 mai 2009 à 17:30
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
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
3 mai 2009 à 17:31
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 *
;-))
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
3 mai 2009 à 17:32
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.
0
bkrqpzef Messages postés 197 Date d'inscription samedi 19 novembre 2005 Statut Membre Dernière intervention 13 juillet 2011 5
3 mai 2009 à 17:46
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 !!
0