OK avec la suppression de $/, et OK aussi avec l'explication du code de djibril
Version imprimable
OK avec la suppression de $/, et OK aussi avec l'explication du code de djibril
Tout pareil ;) l'explication me semble indispensable ici !
Un petit article pour les unilignes en Perl serait intéressant, qu'en pensez-vous ?
J'étais en train de me dire la même chose en lisant la doc perlrun...
Tu veux bien dire un article sur les différentes options de la ligne de commande de perl ? En tout cas, c'est à ça que je pensais car il existe une multitude d'options et surtout, de façon de les utiliser que j'ignorais (et qui me simplifieront grandement l'existence à l'avenir). Et je pense effectivement qu'il est tout à fait possible d'en faire un article !
oui oui, c'est bien ça.
- Insérer une ligne dans un fichier, à une position donnée.
Exemple illustratif pour l'insertion de "toto" à la ligne 4 du fichier text, avec backup du fichier d'origine en .bak :
Code:perl -i.bak -lpe'print "toto" if $.==4' text
- Insérer une ligne dans un fichier, avant chaque ligne correspondant à une regex.
Exemple illustratif pour l'insertion de "toto" avant chaque ligne du fichier text correspondant à la regex /lorem ipsum/, avec backup du fichier d'origine en .bak :
Code:perl -i.bak -lpe'print "toto" if /lorem ipsum/' text
- Insérer une ligne dans un fichier, après chaque ligne correspondant à une regex.
Exemple illustratif pour l'insertion de "toto" après chaque ligne du fichier text correspondant à la regex /lorem ipsum/, avec backup du fichier d'origine en .bak :
Code:perl -i.bak -lne'print ; print "toto" if /lorem ipsum/' text
- Insérer une ligne dans un fichier, après la n-ième ligne correspondant à une regex.
Exemple illustratif pour l'insertion de "toto" après la quatrième ligne du fichier text correspondant à la regex /lorem ipsum/, avec backup du fichier d'origine en .bak :
Code:perl -i.bak -lne'print ; print "toto" if /lorem ipsum/ and ++$occurrence==4' text
- Insérer une ligne dans un fichier en plusieurs positions.
Exemple illustratif pour l'insertion de "toto" aux première, troisième et quatrième lignes du fichier text, avec backup du fichier d'origine en .bak :
Attention, les positions sont relatives aux anciennes positions des lignes. Puisqu'une insertion a déjà eu lieu à la première ligne, l'insertion effectuée à la troisième ligne se retrouve de fait en quatrième ligne, et ainsi de suite. Je n'ai pas pas trouvé de solution simple pour résoudre ce problème.Code:perl -i.bak -lpe'print "toto" if grep {$_==$.} (1,3,4)' text
- Insérer une ligne dans un fichier, après certaines occurrences de lignes correspondant à une regex.
Exemple illustratif pour l'insertion de "toto" après les première, troisième et quatrième lignes du fichier text correspondant à la regex /lorem ipsum/, avec backup du fichier d'origine en .bak :
Code:perl -i.bak -lne'print ; print "toto" if /lorem ipsum/ and ++$occurrence and grep {$_==$occurrence} (1,3,4)' text
Les deux derniers cas commencent à faire un peu artificiel, je le crains.
Très belle contribution, je mettrai les sources à jour dans la journée ou ce weekend. Merci !!
N.B. Il serait intéressant de préciser si ce code fonctionne ou a été testé sous Windows (cygwin ou non), Linux ou Mac.
A vu d'oeil, ça ne devrait pas fonctionner sous Windows en reprenant tes codes. Base toi sur ce message.
Ah, pardon, j'avais oublié de préciser, en effet. Je n'ai pu tester ces unilignes que sous Linux. Je n'ai pas d'autres OS sous la main. Si j'ai bien compris, on peut rendre les unilignes plus compatibles en remplaçant les apostrophes par des guillemets, et les guillemets dans le script par des blocs qq (encore que q suffirait pour mes exemples, et serait peut-être même préférable, ça ce discute).
Voici donc les nouvelles versions :
Code:perl -i.bak -lpe"print qq{toto} if $.==4" text
Code:perl -i.bak -lpe"print qq{toto} if /lorem ipsum/" text
Code:perl -i.bak -lne"print ; print qq{toto} if /lorem ipsum/" text
Code:perl -i.bak -lne"print ; print qq{toto} if /lorem ipsum/ and ++$occurrence==4" text
Code:perl -i.bak -lpe"print qq{toto} if grep {$_==$.} (1,3,4)" text
Code:perl -i.bak -lne"print ; print qq{toto} if /lorem ipsum/ and ++$occurrence and grep {$_==$occurrence} (1,3,4)" text
J'ai copié-collé mon post précédent dans un fichier, et utilisé un uniligne pour obtenir ce qui précède. Rien que pour le fun, voici cet uniligne (qui utilise une astuce shell, et marche peut-être sous Mac) :
C'est un peu alambiqué pour l'extraction et la modification de six lignes, mais j'y trouve un aspect intéressant de façon plus générale : utiliser la commande s/// comme terme de l'opérateur d'étendue .. : c'est la première fois que je fais ça, mais je crois que ça ouvre des pistes marrantes.Code:perl -lne's/"([^"]*)"/qq{$1}/g; s/'"'"'/"/g; print if s#.*?\K(\[code\])#[*]$1#g .. s#(.*?\[/code\]).*#$1#g' unilignes
Un nouvel uniligne qui m'est venu à l'esprit (testé sous Linux uniquement):
Comment déplacer un groupe de lignes d'un ficher vers un autre point dudit fichier ?
Ici, on déplace les lignes 1 à 5 d'un fichier text avant l'actuelle ligne 11 dudit fichier :
C'est un premier jet, il y a pas mal d'améliorations possibles. Cette version ne marche bien que si la ligne cible est strictement postérieure à la dernière ligne du bloc à déplacer.Code:perl -lne"print join qq{$}, @block if $.==11;if ($.==1..$.==5){push @block,$_}else{print}" text
Comment afficher la liste triée des fichiers contenant au moins une ligne correspondant à une regex ?
Exemple avec la regex /lorem ipsum/ sur tout le répertoire courant :
Si l'on veut ajouter le nombre de lignes correspondant à la regex, par fichier :Code:
1
2perl -ne'$files{$ARGV}++ if /lorem ipsum/; END{print map {qq{$_\n}} sort keys %files}' *
Code:
1
2perl -ne'$files{$ARGV}++ if /lorem ipsum/; END{print map {qq{$_ : }.$files{$_}.qq{\n}} sort keys %files}' *
Si l'on veut le nombre total de correspondances distinctes par fichier :
Scripts testés uniquement sous Linux.Code:
1
2perl -ne'$files{$ARGV}++ for /lorem ipsum/g; END{print map {qq{$_ : }.$files{$_}.qq{\n}} sort keys %files}' *
Hello à tous,
quelques petits scripts que j'ai adopté il y a quelques temps en alias en bash... si ça peut servir ;)
Comme à certains moments, j'ai souvent des soucis de conversions binaire <=> hexa <=> décimal, je me suis enregistré ces scripts (source http://www252.pair.com/comdog/master...t_vectors.html). Les noms des alias (type bash) sont assez parlants je pense :
Code:
1
2
3
4
5
6
7
8
9
10
11
12 alias d2h="perl -e 'printf qq|%X\n|, int( shift )'" alias d2o="perl -e 'printf qq|%o\n|, int( shift )'" alias d2b="perl -e 'printf qq|%b\n|, int( shift )'" alias h2d="perl -e 'printf qq|%d\n|, hex( shift )'" alias h2o="perl -e 'printf qq|%o\n|, hex( shift )'" alias h2b="perl -e 'printf qq|%b\n|, hex( shift )'" alias o2h="perl -e 'printf qq|%X\n|, oct( shift )'" alias o2d="perl -e 'printf qq|%d\n|, oct( shift )'" alias o2b="perl -e 'printf qq|%b\n|, oct( shift )'"
Merci !
Peux-tu me donner un exemplaire avec cette configuration :
Q/R : TITRE DE LA QUESTION
Chapitres : uniligne
Testé sous : Linux, Windows, MAC OS X
Un petit texte explicatif serait le bienvenu :ccool:.
:merci:Code:
1
2
3
4
5
6
7
8
9
10
11 alias d2h="perl -e 'printf qq|%X\n|, int( shift )'" alias d2o="perl -e 'printf qq|%o\n|, int( shift )'" alias d2b="perl -e 'printf qq|%b\n|, int( shift )'" alias h2d="perl -e 'printf qq|%d\n|, hex( shift )'" alias h2o="perl -e 'printf qq|%o\n|, hex( shift )'" alias h2b="perl -e 'printf qq|%b\n|, hex( shift )'" alias o2h="perl -e 'printf qq|%X\n|, oct( shift )'" alias o2d="perl -e 'printf qq|%d\n|, oct( shift )'" alias o2b="perl -e 'printf qq|%b\n|, oct( shift )'"
Désolé, je passe un peu moins souvent par ici en ce moment :s
Q/R : Convertir rapidement des nombres entre les bases usuelles (binaire, octale, décimal et hexadécimale)
Chapitres : uniligne
Testé sous : Linux, Windows
Les commandes suivantes permettent de réaliser rapidement des conversions d'une base vers une autre. Sous Linux, utiliser un alias est un bon moyen d'avoir toujours ça sous la main :)
Pour l'explication, elles sont toutes sous le même format, donc je prends la première (ça vaut ce que ça vaut, vous pouvez reformuler :)) :
printf réalise un print formatéCode:
1
2 > perl -e "printf qq|%X\n|, int( shift )" 12 C
qq|...| permet d'éviter l'utilisation des " parfois problématiques sous Windows ou dans les alias. Cette commande est équivalente à "..."
%X\n indique à printf d'afficher le premier argument au format hexadécimal suivi d'un saut à la ligne
int( shift ) est le premier et seul argument du printf (c'est ce qui sera utilisé pour valoriser le %X): shift prend le premier argument de la ligne de commande et int en ressort la valeur entière.
Pour les autres exemples, c'est similaire sauf qu'on utilise une commande hex ou oct pour convertir le nombre passé en paramètre en décimal avant de l'afficher par printf.
- décimal > hexadécimal
Code:perl -e "printf qq|%X\n|, int( shift )"
- décimal > octal
Code:perl -e "printf qq|%o\n|, int( shift )"
- décimal > binaire
Code:perl -e "printf qq|%b\n|, int( shift )"
- hexadécimal > décimal
Code:perl -e "printf qq|%d\n|, hex( shift )"
- hexadécimal > octal
Code:perl -e "printf qq|%o\n|, hex( shift )"
- hexadécimal > binaire
Code:perl -e "printf qq|%b\n|, hex( shift )"
- octal > hexadécimal
Code:perl -e "printf qq|%X\n|, oct( shift )"
- octal > décimal
Code:perl -e "printf qq|%d\n|, oct( shift )"
- octal > binaire
Code:perl -e "printf qq|%b\n|, oct( shift )"
Il est envisageable d'utiliser la version octal > * pour convertir du binaire ou de l'hexadécimal en spécifiant le type.
Exemples :
A noter qu'il est possible, sous Linux, de les mettre en alias, par exemple:Code:
1
2
3
4 > perl -e "printf qq|%d\n|, oct( shift )" 0xA 10 > perl -e "printf qq|%d\n|, oct( shift )" 0b0110 6
Code:
1
2
3 > alias d2h="perl -e 'printf qq|%X\n|, int( shift )'" > d2h 253 FD
:merci:
Convertir rapidement des nombres entre les bases usuelles (binaire, octale, décimal et hexadécimale) Fait
Bonjour,
Je reprends ici la réponse que j'ai faite à la question suivante (en modifiant un peu ma réponse pour que ça marche aussi dans une fenêtre MS-DOS).
Question: Comment faire un uniligne qui permette de compter le nombre de mots et le nombre de phrases dans un morceau de texte passé en paramètre?
Chapitre : unilignes
Testé sous : Linux, HP-UX, Windows (MS-DOS)
Voici une solution minimale qui marche pour compter le nombre de mots (marche sous Unix; sous Windows, remplacer les apostrophes par des guillemets):
Et une solution plus complète comptant les mots et les phrases:Code:
1
2 $ perl -e '$_ = shift; $wc = split; print qq/$wc\n/;' "ma phrase à compter" 4
Version avec un echo et un pipe (donc, sous Unix uniquement):Code:
1
2
3 perl -e '$_ =shift; $wc = split /\s/; $pc = split /\./; print qq/ $wc mots\n $pc phrases\n/;' "ma phrase à compter. Ma deuxième phrase." 7 mots 2 phrases
Compter le nombre de mots pour chaque ligne d'un fichier, ici le fichier "essai.txt" (marche sous Unix, marche sous Windows toujours en remplaçant les apostrophes par des guillemets):Code:
1
2 $ echo "les poules du couvent couvent." | perl -ne '$wc = split; print $wc, " mots \n";' 5 mots
Code:
1
2
3
4
5
6
7
8
9 $ perl -ne '$wc = split; print qq/$. : $wc \n/;' essai.txt 1 : 12 2 : 12 3 : 11 4 : 14 5 : 4 6 : 5 7 : 0 ...
Merci pour ta participation, je la rajouterai dans la FAQ. Juste une précision, une phrase se termine certes par un point, mais peut aussi se terminer par un point d'exclamation ou un point d'interrogation.
Code:
1
2
3
4
5
6
7
8
9 >perl -e "$_ =shift; $wc = split /\s/; $pc = split /\./; print qq/ $wc mots\n $pc phrases\n/;" "ma phrase à compter. Ma deuxième phrase. Une autre ? Ok :-) ! Merci." 15 mots 3 phrases => FAUX >perl -e "$_ =shift; $wc = split /\s/; $pc = split /[\.\?\!]/; print qq/ $wc mots\n $pc phrases\n/;" "ma phrase à compter. Ma deuxième phrase. Une autre ? Ok :-) ! Merci." 15 mots 5 phrases
Merci de ta correction, tu as parfaitement raison. J'avais juste fait un truc rapide pour donner une idée de la solution à la personne qui avait posé la question, mais pour un uniligne plus général, il vaut mieux être plus complet et tenir compte des autres terminateurs de phrases.
J'ai fait un wiki au bureau avec une série de scripts unilignes utiles sous Unix, je les posterai ici à l'occasion.