terminal (syntaxe)

obiwan67

Membre actif
27 Avril 2003
211
1
bonjour

quel est l'opérateur logique dans le terminal pour dire différent ?

dans un tuto unix c'était != mais dans le terminal il veut pas !!!

merci
 
Salut,

Les opérations de test logiques dans un script shell utilisent la commande "test" (faire "man test" dans le Terminal). Cette commande est souvent abrégée en [ ], comme dans
Bloc de code:
if [ $chaine1 != $chaine2 ]; then
      echo "Chaines différentes"
   fi
Attention à bien respecter les espaces entre [, le test et ] !
 
salut

j'ai pas bien suivi là

le but étant de faire l'inverse de ça

sed "s/toto/TOTO/g" fichier.txt > fichier2.txt va changer toutes les occurences de la chaîne toto par TOTO (toutes les chaînes toto rencontrées sont changées)

CAD si c'est différent de toto changer par TOTO, comment s'y prendre ?

merci
 
Ah mais il fallait préciser ce que tu voulais faire! En fait tout va dépendre des commandes que tu utilises. Maintenant que je sais que tu utilises sed, ce qu'il faut faire pour lui indiquer de remplacer toutes les chaines qui ne sont pas toto par TOTO, c'est d'utiliser les expressions régulières (ou regexp). Je cherche. et je poste si je trouve...

[edit]
Ton pb est plus sioux que prévu, surtout avec les expression régulières. On pourrait écrire un shell script qui ferait ça, mais en une seule ligne de sed, c'est och à écrire. Essaie quand même ça:
Bloc de code:
sed s/(.*)(toto)(.*)/(TOTO)\2(TOTO)/g
Il se peut que sed considère les parenthèses comme des caractères classiques, et que pour leur donner un sens spécial (ici grouper les patterns) tu doive mettre un \ devant chacune d'entre elles (ouvrante et fermante).
Ca donne quoi?
[/edit]
 
c'est pas au point lol ca marche pas ni dans l'un ni dans l'autre des cas

G5:~/Desktop/log michel$ sed s/(.*)(donald)(.*)/(michel)\2(NONE)/g test2.log > test3.log
-bash: syntax error near unexpected token `('
G5:~/Desktop/log michel$ sed s/\(.*\)\(donald\)\(.*\)/\(michel\)\2\(NONE\)/g test2.log > test3.log
G5:~/Desktop/log michel$

bon dans le deuxième cas il ne rale pas mais il n'y a pas de différence entre le fichier de départ et le fichier d'arrivé

sinon en shell script ca donnerais quoi ?
 
J'ai baffouillé un petit script (avec commentaires et tout :)) en Perl qui devrait faire ce que tu veux. Copie-colle le texte ci dessous dans un fichier texte, que tu sauvegarderas sous un nom quelconque (genre "replace.pl" (.pl est l'extension par défaut des fichiers Perl, mais tu peux l'omettre) :
Bloc de code:
#/usr/bin/env perl
   
   # Test des arguments passés à l'appel
   if ($#ARGV != 3) {
   	print "Argument manquant!\n";
 	print("Syntaxe : ./$0 <chaine_a_conserver> <chaine_de_remplacement> <fichier_entree> <fichier_sortie>\n");
   	exit(1);
   }
   
   # Récupération des arguments
   $keep_string = @ARGV[0];
   $chg_string = @ARGV[1];
   $infile = @ARGV[2];
   $outfile = @ARGV[3];
   
   # Ouverture des fichiers d'entrée et de sortie
   open(INF, "$infile") or die "Impossible d'ouvrir le fichier $infile";
   open(OUTF, ">$outfile") or die "Impossible de créer le fichier $outfile";
   
   # Boucle de lecture du fichier ligne à ligne
   while (<INF>) {
   	# Récupère chaque mot dans le tableau @words
   	my @words = split(/ /, $_);
   	my $new_string = "";
   	# Remplace tous les mots qui ne sont pas egaux à $keep_string
   	foreach(@words) {
   		if ($_ ne $keep_string) {
   			$new_string .= $chg_string . ' ';
   		} else {
   			$new_string .= $_ . ' ';
   		}
   	}
   	# Ecrit la chaine transformée dans le fichier de sortie
   	syswrite(OUTF, $new_string . "\n");
   }
   
   # Fermeture des fichiers et fin
 close(INF) and close(OUTF);
Ensuite utilise une fenêtre de terminal et tape la commande suivante pour rendre ton script exécutable :
Bloc de code:
chmod 755 replace.pl
Bien évidemment, tu te seras au préalable rendu dans le répertoire contenant ton script Perl en utilisant la commande "cd". Et tu auras remplacé "replace.pl" par le nom que tu auras donné à ton script si besoin est.
Ensuite pour exécuter le script tu tapes :
Bloc de code:
replace.pl <chaine_a_conserver> <chaine_a_remplacer> <fichier_entree> <fichier_sortie>
en remplaçant tous les arguments entre <> par ce que tu veux! :p Il y avait surement moyen de faire plus simple mais bon...

Tu devrais apprendre le shell bash et/ou un langage interprété comme Perl ou Python si tu as souvent besoin de faire des opérations comme celle-ci, le retour sur investissement est largement positif car ce sont des langages puissants!

Ca vaut bien un coup d'boule non? ;)
 
  • J’aime
Réactions: Macounette
heu pour cette ligne c'est ça ?

print("syntaxe : ./$0 <chaine_a_conserver> <chaine_de_remplacement> <fichier_entree> <fichier_sortie>")

et pour la chaine a comparer je voudrais comparer sur une parti de la chaine seulement
est ce que cela fonctionnerait

<chaine_a_conserver>
<hit: .*: ^7-^4V^7P^1C^7- .* hit>
 
Je pense que ce topic mériterait maintenant d'être déplacé dans le forum "Programmation"...

obiwan67 a dit:
heu pour cette ligne c'est ça ?

print("syntaxe : ./$0 <chaine_a_conserver> <chaine_de_remplacement> <fichier_entree> <fichier_sortie>")
Je ne comprends pas ce que tu veux dire. Cette ligne sert juste à afficher une aide sur la manière dont on utilise le script. Si c'est pour le \n à la fin, il n'est pas obligatoire. Il sert juste à faire un saut de ligne.

obiwan67 a dit:
et pour la chaine a comparer je voudrais comparer sur une parti de la chaine seulement
est ce que cela fonctionnerait

<chaine_a_conserver>
<hit: .*: ^7-^4V^7P^1C^7- .* hit>
OK je comprends mieux. j'ai mis les arguments entre <> mais il ne faut pas les utiliser. C'est une convention de notation quand on décrit la manière d'appeler un programme en ligne de commande, cela permet de repérer les arguments obligatoire et/ou optionnels. J'aurais pu les mettre entre [] ou entre (). En gros, voici un exemple :
replace.pl Gardez-moi virez-les donnees.txt resultat.txt
De la manière dont est écrit le script, il travaille sur les éléments du fichier qui se situent entre deux caractères "espace". C'est la ligne suivante qui fait la séparation:
Bloc de code:
my @words = split(/ /, $_);
Tu remarqueras que le premier argument de la fonction split est une expression régulière comme celles que tu as l'habitude d'utiliser avec sed. Il s'agit de / / (l'espace entre les 2 slashes est important!) qui reconnait tous les espaces dans un texte. split() va donc récupérer tous les éléments séparés par des espaces et les stocker dans le tableau @word, et ce pour chaque ligne du fichier (stockée dans la variable spéciale $_).

Mais tu peux modifier le script pour préciser les délimiteurs afin de faire des recherches sur des parties de chaine. :) Dans ton cas
obiwan67 a dit:
hit: .*: ^7-^4V^7P^1C^7- .* hit
, supposons que ton délimiteur soit le caractère -, tu définiras le premier argument de split() par:
Bloc de code:
my @words = split(/-/, $_);
. Si ton délimiteur est ^, alors tu écriras
Bloc de code:
my @words = split(/\^/, $_);
Le backslash \ est nécessaire devant ^ car ^ est un caractère spécial des expressions régulières qui désigne le début d'une ligne. Et pour lui faire perdre son sens spécial on met un \ devant.

Tu peux aussi définir plusieurs délimiteurs. Par exemple pour retourner les sous-chaines comprises entre les caractères t: et ^, tu écriras
Bloc de code:
my @words = split(/"t:"C/, $_);
. Tout le jeu pour toi consiste donc à trouver les délimiteurs qui t'intéressent, qui peuvent être des caractères, des bouts de chaines (à mettre entre "" (à confirmer, je ne suis plus sur)) et des caractères non imprimables (comme le saut de ligne \n, la tabulation \t, etc. Ah le backslash est \\ of course :)
 
Leehalt a dit:
Je pense que ce topic mériterait maintenant d'être déplacé dans le forum "Programmation"...

Je ne comprends pas ce que tu veux dire. Cette ligne sert juste à afficher une aide sur la manière dont on utilise le script. Si c'est pour le \n à la fin, il n'est pas obligatoire. Il sert juste à faire un saut de ligne.
oui ca j'avais capté mais la ligne dont on parle est comme ça sur ta copie d'écran
print("syntaxe : ./$0 <chaine_a_conserver> <chaine_de_remplacement> <fichier_entre
alors je ne sais pas trop comment terminer avec les guillemets
car avec ça il me met une erreur
print("syntaxe : ./$0 <chaine_a_conserver> <chaine_de_remplacement> <fichier_entree> <fichier_sortie>")

OK je comprends mieux. j'ai mis les arguments entre <> mais il ne faut pas les utiliser. C'est une convention de notation quand on décrit la manière d'appeler un programme en ligne de commande, cela permet de repérer les arguments obligatoire et/ou optionnels. J'aurais pu les mettre entre [] ou entre (). En gros, voici un exemple :
replace.pl Gardez-moi virez-les donnees.txt resultat.txt
De la manière dont est écrit le script, il travaille sur les éléments du fichier qui se situent entre deux caractères "espace". C'est la ligne suivante qui fait la séparation:
Bloc de code:
my @words = split(/ /, $_);
Tu remarqueras que le premier argument de la fonction split est une expression régulière comme celles que tu as l'habitude d'utiliser avec sed. Il s'agit de / / (l'espace entre les 2 slashes est important!) qui reconnait tous les espaces dans un texte. split() va donc récupérer tous les éléments séparés par des espaces et les stocker dans le tableau @word, et ce pour chaque ligne du fichier (stockée dans la variable spéciale $_).

Mais tu peux modifier le script pour préciser les délimiteurs afin de faire des recherches sur des parties de chaine. :) Dans ton cas , supposons que ton délimiteur soit le caractère -, tu définiras le premier argument de split() par:
Bloc de code:
my @words = split(/-/, $_);
. Si ton délimiteur est ^, alors tu écriras
Bloc de code:
my @words = split(/\^/, $_);
Le backslash \ est nécessaire devant ^ car ^ est un caractère spécial des expressions régulières qui désigne le début d'une ligne. Et pour lui faire perdre son sens spécial on met un \ devant.

Tu peux aussi définir plusieurs délimiteurs. Par exemple pour retourner les sous-chaines comprises entre les caractères t: et ^, tu écriras
Bloc de code:
my @words = split(/"t:"C/, $_);
(/"t:"C/, $_) ou (/"t:""C"/, $_) ?
mes delimiteurs sont dans ce cas "hit:" et " hit"
en fait le gros souci que j'ai c'est que ce qui est en rouge n'est jamais pareil et je ne connais même pas la longueur de la chaine car elle est variable
hit: .*: ^7-^4V^7P^1C^7- .* hit
la syntaxe est elle juste comme ça ?
. Tout le jeu pour toi consiste donc à trouver les délimiteurs qui t'intéressent, qui peuvent être des caractères, des bouts de chaines (à mettre entre "" (à confirmer, je ne suis plus sur)) et des caractères non imprimables (comme le saut de ligne \n, la tabulation \t, etc. Ah le backslash est \\ of course :)
 
obiwan67 a dit:
(/"t:"C/, $_) ou (/"t:""C"/, $_) ?
Bon j'ai fait une erreur (normal, vu la taille de mon poste), vu que dans mon exemple je prends comme délimiteurs t: et ^ l'expression régulière est /"t:"\^/.
obiwan67 a dit:
mes delimiteurs sont dans ce cas "hit:" et " hit"
en fait le gros souci que j'ai c'est que ce qui est en rouge n'est jamais pareil et je ne connais même pas la longueur de la chaine car elle est variable
hit: .*: ^7-^4V^7P^1C^7- .* hit
la syntaxe est elle juste comme ça ?
La longueur de la chaine n'est pas un pb grâce aux expressions régulières. T'as qu'à utiliser /"hit"/ comme expression régulière. Tu peux aussi essayer /"hit":?/, qui devrais trouver hit et hit: (normalement :))