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

34 réponses

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Salut,

Par exemple
ls ../*/*/*/* | xargs sed -i 's#bateau #maison #'
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Salut et merci pour la réponse. :)
Cependant :
bash: /bin/ls: Liste d'arguments trop longue
sed: pas de fichiers en entrée
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Essaie
find ../ -type f -exec  sed -i 's#bateau #maison #' {} \;
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Je teste.
Ca à l'air de marcher, Merci.
(Ca risque de mettre du temps pour vérifier si tout se passe bien)
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Cool ça marche. Mais je n'y comprend rien :).
Il faut que je lance :
sed -i 's#bateau #maison #' ../*/*/*/*

et
sed -i 's#bateau #maison #' ../*/*/*/*/*
(avec un /* de plus que l'autre)
Est ce que :
find ../ -type f -exec  sed -i 's#bateau #maison #' {} \;

peut remplacer les deux ?
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Je répond à ma propre question : OUI !!!!!! :p
Merci pour tout.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Tu as bien répondu ;-)

De rien ;-))
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

De toute façon tu veux traiter tous les fichiers de répertoire parent.
Pourquoi pas utiliser le chemin complet de répertoire parent?

De toute façon ce ça que ../ fait dans dans le find.
Tu n'as pas besoin de tous ces étoiles

Pour plus de clarté je te conseille de mettre le chemin complet de répertoire parent
Dans ce répertoire tu n'as que des fichiers texte? Les fichiers ont une extension ou pas (.txt par exemple)
Je ne pense pas que c'est ça que tu veux.
find /chemin/complet -type f -exec  sed -i 's#bateau #maison #' {} \;
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Hum voilà. En fait ça fonctionne parfaitement mais le premier fichier SH modifie également les autres fichiers SH. :D
Comment le limiter aux fichiers avec extension .txt par exemple ?
Messages postés
40805
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 837
Salut,
find /chemin/complet -type f -name "*.txt" -exec  sed -i 's#bateau #maison #' {} \;
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
OK merci. :)
Et un nouveau problème fun mais à part tout changer je ne vois pas de solution :
D'après de rapides estimations, mon programme met 1 an et demi pour s'executer... :o
Je crois que ça ne va pas le faire...

Une idée pour limiter sed aux 10 dernières lignes avant les dix dernières lignes du fichier ? (Je crois que je demande un peu trop à la machine là :s)
Messages postés
40805
Date d'inscription
jeudi 28 août 2003
Statut
Modérateur
Dernière intervention
10 août 2020
4 837
Peut être voir avec un autre programme comme "Perl".

Une idée pour limiter sed aux 10 dernières lignes avant les dix dernières lignes du fichier ?
Hum... on va dire que techniquement c'est possible (plus particulièrement avec "ed" plutôt que "sed"), mais ça serait encore plus lourd, donc plus long ;-((

Édit : Pour te donner une idée avec "ed" :
[tmpfs]$ cat plop
Ligne 1
Ligne 2
Ligne 3
Ligne 4
Ligne 5
Ligne 6
Ligne 7
Ligne 8
Ligne 9
Ligne 10
Ligne 11
Ligne 12
Ligne 13
Ligne 14
Ligne 15

[tmpfs]$ ed -s plop <<< $'H\n,-10;+5 s/Ligne/& n° /\n,w'

[tmpfs]$ cat plop
Ligne 1
Ligne 2
Ligne 3
Ligne 4
Ligne n°  5
Ligne n°  6
Ligne n°  7
Ligne n°  8
Ligne n°  9
Ligne n°  10
Ligne 11
Ligne 12
Ligne 13
Ligne 14
Ligne 15
[tmpfs]$
;-))
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Salut,

Tu as combien de fichiers?
find /chemin/complet -type f -name "*.txt" | wc -l
Tu as combien de remplacements à faire dans tes fichiers?
find . -name '*.txt' -exec grep -c bateau {} \;|awk '{SUM += $1}END{print SUM}'
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
50 000 commandes sed ciblant chacune dans les 5.2 Go de données. :'(
Des images dans le tas :p
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Affiche le résultat des commandes que je t'ai donné ;-)

mon programme met 1 an et demi pour s'executer
Ici on parle d'une commande.
Ton programme contient autre chose?!

Tes estimations se basent sur quoi?
J'ai traiter des fichiers de 600 Mo et je n'ai pas passer des heures pour le faire, donc 5 Go dans 1 an et demi c'est un peut trop quand même.


Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
(En fait c'est un prog en C qui ecrit un fichier .sh qui s'éxecute, celui-ci est constitué de 50 000 commandes de modifications de type sed, mais si l'une d'elle devient plus rapide ça affectera le reste, qui sera modifié également)

find /chemin/complet -type f -name "*.txt" | wc -l

me rend 34 148

Tu as combien de remplacements à faire dans tes fichiers?
Alors euh un seul par commande dans chaque dossier après le ../

En fait il y a 25 dossier (au niveau du chemin ../). Et dans chaque dossier je ne rencontre cette suite qu'une seule fois. Possible de lui dire de passer au dossier d'après s'il a trouvé la chaine ? :p
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Et la deuxième commande?
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Il y pense toujours à la deuxième commande. Elle va arriver surement ^^
Théoriquement ça sera 25. :)
[Edit]Confirmation le résultat est 25 :)

Pour l'estimation ben, j'ai chronométré le temps d'éxecution d'une commande sed et j'ai multiplié le tout par le nombre de commandes. :D
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Impossible.
La deuxième commande doit afficher le nombre de lignes qui contient le mots bateau (ce le mot à remplacer).

Donc si tu as 30 000 fichiers et qu'il y a un remplacement par fichier tu dois avoir le résultat de la deuxième commande au moins égal avec le nombre de fichiers.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Re,

Un exemple chez moi sur 5 fichiers
$ pwd
/home/lami20j/toolong
$ ls -1
fichier1.txt
fichier2.txt
fichier3.txt
fichier4.txt
fichier5.txt
$ ls -1 | wc -l
5
$ find . -name '*.txt' | wc -l
5
$ find . -name '*.txt' -exec grep -c bateau {} \;|awk '{SUM += $1}{print SUM}'
23
46
69
92
115
$ find . -name '*.txt' -exec grep -c bateau {} \;|awk '{SUM += $1}END{print SUM}'
115
Messages postés
197
Date d'inscription
samedi 19 novembre 2005
Statut
Membre
Dernière intervention
13 juillet 2011
6
Explication du dessus en détail :

../ contient
dossier1
dossier2
dossier3
.
.
.
dossier24
dossier25

dans chacun de ces dossiers, il y a d'autres dossiers etc ... et des fichiers .txt à modifier
cependant le mot "bateau" (c'est un exemple évidemment) ne revient qu'une seule fois par dossier.

Exemple : Dans "dossier1" il n'y a qu'un seul fichier .txt qui contient le mot ''bateau" et en plus ce mot n'est présent qu'une seule fois.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 522
Salut,

Je n'ai pas besoin d'exemples. Tu as un cas concret. Donc tu as besoin de précision.

Si un seul fichier contient le mot bateau et en plus une seule fois alors je ne vois pas pourquoi tu as besoin de remplacer les 10 dernières lignes avant les 10 dernières.
Pour moi ton cas n'est pas clair et en ce cas je ne peux pas t'apporter de l'aide.

En plus des 2 commandes que je t'ai donné et tu ne veux toujours pas m'afficher le résultat, installe le paquet tree et ensuite tape la commande
 tree -P "*.txt" -o log
Tu peux mettre le fichier compressé sur cjoint.com