Commandes shell pour modifier des lignes

Résolu/Fermé
daslook - 1 janv. 2010 à 19:18
 daslook - 2 janv. 2010 à 12:21
Bonjour,
je suis sur ubuntu et j'entretiens plusieurs petits sites, notamment avec des photos, je fais souvent des modifications et du coup mon arborescence genre, ou alors je change de code pour les galeries etc.. du coup j'ai des modifications a faire.. et dans un tas de fichiers... mais à la main c'est pénible et comme j'ai un ordinateur pour bosser à ma place normalement, je me suis mis en quête d'une solution.. informatique :)

Après quelques recherches j'en ai conclus que le plus "simple" serais de faire faire ça par un script shell... j'ai donc cherché dans cette directions mais je ne suis pas assez aguerrit en programmation pour avoir une vraie direction, et les sites qui expliquent le shell partent souvent du début (normal) et bon.. j'y comprend pas tout là non plus...

voici une ligne type de mon fichier :

<a href="javascript:PopupImage('membre/images/image01.jpg')"><img align="center" src="membre/thumbnails/image01.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>

dans cette ligne, qui existe à x exemplaires, je veux remplacer systématiquement :

membre/images/image01.jpg

par :

membre/images/image1_4.jpg (ce qui est dans le title="......jpg")

Je pense que c'est faisable, j'ai connu quelqu'un qui m'avait fait un script pour ça il y a quelques années mais j'ai perdu le script...

Merci d'avance si vous pouvez m'aider.
A plus tard.
bonne année !
daslook
A voir également:

14 réponses

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
1 janv. 2010 à 20:21
Salut,

Un truc du genre (un peu lourd et tordu) devrait le faire (mais faudra quand même cibler la ligne en question en espérant quelle soit seule sur une ligne) :

[tmpfs]$ cat fichier.html
<a href="javascript:PopupImage('membre/images/image01.jpg')"><img align="center" src="membre/thumbnails/image01.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>

[tmpfs]$ sed 's#\([^>]*/\)\([^)]*\)\(.*src="[^"]*/\)\([^"]*\)\(".*\)\(title="\)\([^"]*\)\(".*\)#\1\7'\''\3\7"\5\6\7\8#' fichier.html

<a href="javascript:PopupImage('membre/images/image1_4.jpg')"><img align="center" src="membre/thumbnails/image1_4.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>

[tmpfs]$ 

;-))

Édit : Changement de :

\([^"]*"\)\(.*\)

par :

\([^"]*\)\(".*\)
0
JessayeDeTrouver Messages postés 270 Date d'inscription mercredi 9 septembre 2009 Statut Membre Dernière intervention 4 mai 2012 47
1 janv. 2010 à 21:08
jipicy t'es trop fort !

c'est la preuve que linux est mieux que windows
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
1 janv. 2010 à 23:03
Salut,

je sais pas si je vais répondre à ton problème mais j'ai fais un petit script (en perl désolé :( ) qui va permettre de remplacer un terme par un autre dans tous les fichiers (texte, html etc) d'un dossier et tous les fichiers de ses sous-dossiers et ainsi de suite récursivement, je pense que c'est bon mais faut le tester un peu pour voir pour lever les erreurs qui m'auraient échappés. A utiliser avec précautions car il modifie tous les fichiers d'une arborescence (hors fichiers binaires et liens symboliques). A ajouter que la casse est prise en compte.

#!/usr/bin/perl

use strict;
use warnings;

my @fichiers;

print "Entrer le chemin complet du répertoire : \n";
my $rep = <STDIN>;

chomp($rep);

if(!(-e $rep))
{
	warn "Pas de dossier de ce nom";
	
	exit(0);
}

print "Entrer la chaine de caractère à remplacer : \n";
my $chaine1 = <STDIN>;

chomp($chaine1);

print "Entrer la chaine de caractère en remplacement : \n";
my $chaine2 = <STDIN>;

chomp($chaine2);

print "Attention, vous vous apprêtez à remplacer $chaine1 par $chaine2 dans tous les fichiers du répertoire $rep, taper O pour continuer : \n";
my $confirmation = <STDIN>;

chomp($confirmation);

if($confirmation !~ /O|o/)
{
	exit(0);
}

&parcoursArborescence($rep);

&changeTerme();


##Déclaration des fonctions


sub parcoursArborescence
{
	my($rep) = shift;
	
	opendir(REP, $rep);
	
	my @liste = readdir(REP);
	
	closedir(REP);
	
	foreach my $nomfichier (@liste)
	{
		if($nomfichier ne "." && $nomfichier ne ".." && $nomfichier !~ /^\./)
		{
			my $fichier = $rep."/".$nomfichier;
			
			if(-f $fichier && !(-B $fichier) && !(-l $fichier))
			{
				push(@fichiers, $fichier);
			}
			
			if(-d $fichier)
			{
				&parcoursArborescence($fichier);
			}
		}
	}
}

sub changeTerme
{
	foreach my $fichier (@fichiers)
	{	
		my @temp;
		my $estModifie = 0;
		
		open(FICHIER, "$fichier");
		
		while(<FICHIER>)
		{
			push(@temp, $_);
		}

		close(FICHIER);
		
		open(FICHIER, ">$fichier");
		
		foreach my $temp (@temp)
		{		
			if($temp =~ /$chaine1/)
			{
				$estModifie = 1;
			}
			
			$temp =~ s/$chaine1/$chaine2/g;
			
			print FICHIER $temp;
		}
		
		close(FICHIER);
		
		if($estModifie == 1)
		{
			print "Modifications effectuées dans $fichier\n";
		}
	}
}
0
Salut jipicy et merci pour ta réponse,
bon, je suppose après m'être à l'instant documenté (non sans avoir tenté de tout entrer à l'arrache deux ou trois fois...) qu'il faut que je monte un tmpfs en prem's ?
Bon remarque ça a l'air pas mal, j'ai trouvé un blog qui explique ça bien.

Je fais tout ça, et je tente à nouveau :)

merci
a plus tard
daslook
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
1 janv. 2010 à 23:31
Non le "tmpfs" c'est mon répertoire de test, tu n'en as pas besoin.

En fait chez moi tmpfs c'est un lien vers "/dev/shm" (système de fichiers temporaire).
Je fais tous mes tests là-dedans et c'est effacé à chaque reboot de la machine...
0

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

Posez votre question
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
1 janv. 2010 à 23:22
Donc tu coup ce que je viens de te filer ne peux pas t'aider alors ?
0
bonsoir miramaze,
merci pour ton aide
ouch, bon déjà je nage en shell alors en perl.. c'est super intéressant en tout cas, je vais voir si je chope de la doc pour avoir des bases avant de faire n'importe quoi, mais clairement que ça m'intéresse pour plus tard.. ça laisse songeur

a plus tard
daslook
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
1 janv. 2010 à 23:35
Tu sais le script est tout prêt, il va te demander lui-même les infos de répertoire, le terme que tu veux remplacer et par quoi tu veux le remplacer, à saisir dans le terminal, y'a juste à le lancer, y'a rien à modifier. T'as juste à le copier coller dans un fichier texte, à l'enregistrer (mets l'extension pl pour faire plus joli) et à appeller ton programme comme ça : perl nomduprogramme enfin tu le sais peut-être déjà je veux pas te prendre pour une bille.
0
Ok j'ai lu tout ça,

mais la ligne que j'utilise dans mon exemple est juste un exemple, les nom des fichiers changent tout le temps... ce script ne fonctionne que si je lui dit quoi mettre exactement à la place de quoi, non ? (mais je me trompe peux être : je suis une bille en perl et shell)

voici par exemple l'état actuel du début d'un fichier type :

<a href="javascript:PopupImage('membreBidule/images/back03.jpg')"><img align="center" src="membreBidule/thumbnails/image1_4.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>


<a href="javascript:PopupImage('membreBidule/images/back03.jpg')"><img align="center" src="membreBidule/thumbnails/image1_1.jpg" width="154" height="118" title="image1_1.jpg" border="0"></a>


<a href="javascript:PopupImage('membreBidule/images/back03.jpg')"><img align="center" src="membreBidule/thumbnails/image1_6.jpg" width="154" height="118" title="image1_6.jpg" border="0"></a>


<a href="javascript:PopupImage('membreBidule/images/back03.jpg')"><img align="center" src="membreBidule/thumbnails/image1_7.jpg" width="154" height="118" title="image1_7.jpg" border="0"></a>

___

le title change à chaque ligne..
bon je vais tenter quand même

merci en tout cas ça me donne des pistes
a plus tard
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
2 janv. 2010 à 00:38
Et bien le script remplace toutes les occurences d'un termes par un autre dans tous les fichiers et et tous les sous répertoires d'un répertoire donc oui. Après si c'est toujours la même configuration et que c'est le title qui doit remplacer le reste alors effectivement il faut modifier et je n'avais pas pigé ce que tu voulais.
0
en tout cas j'ai testé et je l'ai fait tourner, ça a fonctionné :)
0
Galawin Messages postés 835 Date d'inscription lundi 27 août 2007 Statut Membre Dernière intervention 17 novembre 2013 123
2 janv. 2010 à 00:40
Ya pas une fonction dans gedit pour ça ?
"Chercher et remplacer" non ?

edit : ah non j'avais pas comprit le problème... J'ai rien dit ^^
0
sinon avec le shell j'ai fais des tentatives aussi et j'obtiens ce message :

bash: Erreur de syntaxe près du symbole inattendu « < »

bon, je cherche le "<" en question mais franchement..

mon truc est peut être pas faisable sous cette forme en fait

a plus tard en tout cas
daslook
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
2 janv. 2010 à 01:15
Re,
j'ai revu ma copie pour coller exactement à l'exemple plus haut du coup :

<a href="javascript:PopupImage('membreBidule/images/back03.jpg')"><img align="center" src="membreBidule/thumbnails/image1_4.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>

il prend le nom donné par title soit ici image1_4.jpg, il prend l'occurence à remplacer ici back03.jpg et il remplace la seconde par la première (si tu as plusieurs fois la seconde dans la ligne il la remplace par exemple si dans src=" tu as aussi la seconde il la remplace par la première) ce qui donne au final :

<a href="javascript:PopupImage('membreBidule/images/image1_4.jpg')"><img align="center" src="membreBidule/thumbnails/image1_4.jpg" width="154" height="118" title="image1_4.jpg" border="0"></a>

Et ça encore une fois pour tous fichiers d'un répertoire et de tous ses sous-répertoires récursivement. Il faut que tes lignes à remplacer soit construites sur le même modèle que ci dessus.

Voici le script modifié :


#!/usr/bin/perl

use strict;
use warnings;

my @fichiers;

print "Entrer le chemin complet du répertoire : \n";
my $rep = <STDIN>;

chomp($rep);

if(!(-e $rep))
{
	warn "Pas de dossier de ce nom";
	
	exit(0);
}

print "Attention, vous vous apprêtez à modifier certains fichiers du répertoire $rep, taper O pour continuer : \n";
my $confirmation = <STDIN>;

chomp($confirmation);

if($confirmation !~ /O|o/)
{
	exit(0);
}

&parcoursArborescence($rep);

&changeTerme();


##Déclaration des fonctions

sub parcoursArborescence
{
	my($rep) = shift;
	
	opendir(REP, $rep);
	
	my @liste = readdir(REP);
	
	closedir(REP);
	
	foreach my $nomfichier (@liste)
	{
		if($nomfichier ne "." && $nomfichier ne ".." && $nomfichier !~ /^\./)
		{
			my $fichier = $rep."/".$nomfichier;
			
			if(-f $fichier && !(-B $fichier) && !(-l $fichier))
			{
				push(@fichiers, $fichier);
			}
			
			if(-d $fichier)
			{
				&parcoursArborescence($fichier);
			}
		}
	}
}

sub changeTerme
{
	foreach my $fichier (@fichiers)
	{	
		my @temp;
		my $estModifie = 0;
		
		open(FICHIER, "$fichier");
		
		while(<FICHIER>)
		{
			push(@temp, $_);
		}

		close(FICHIER);
		
		open(FICHIER, ">$fichier");
		
		foreach my $temp (@temp)
		{		
			
			if( $temp =~ /<a href(.*?)\/(\w*)\.(\w*)(.*?)><img align(.*?)title\=\"(.*?)\"(.*?)>/)
			{
				my $nouveau = $6;
				my $ancien = $2.".".$3;
				
				$temp =~ s/$ancien/$nouveau/;
				
				print "Remplacement de $ancien par $nouveau\n";
				
				$estModifie = 1;
			}
			
			print FICHIER $temp;
		}
		
		close(FICHIER);
		
		if($estModifie == 1)
		{
			print "Modifications effectuées dans $fichier\n";
		}
	}
}
0
ah ouai, ça fonctionne super bien
c'est dingue

super merci, je vais "étudier" (lire des tutos, bidouiller des script..) le perl de plus près, avant ça ça me disait franchement rien :)

merci beaucoup
a plus tard
daslook
0
miramaze Messages postés 1429 Date d'inscription mercredi 29 juillet 2009 Statut Contributeur Dernière intervention 1 mai 2022 92
2 janv. 2010 à 01:46
De rien.

Bon, c'étais bien ça que tu voulais alors.

C'est super cool le Perl avant que je m'y mette ça me disait trop rien non plus mais maintenant, c'est mon langage préféré mais la solution de jipicy à base du bon vieux shell était nickel aussi...

Tu peux mettre le post en résolu alors si ton problème est réglé.
0
Oui, j'ai mis le post en "résolu" :)

je vais revoir la commande shell, je n'y arrive pas, je dois faire une erreur quelque part... je vais chercher

Merci à tous
bon weekend
0