gauret Posted June 14, 2006 Share Posted June 14, 2006 Oué, moi non plus ! J'adore ce topic :) Sinon, dommage qu'on puisse pas le piper dans un correcteur grammatical après, parce qu'à l'impératif il n'y a pas de "s" à "arrête".... ;o) Link to post Share on other sites
theocrite Posted June 14, 2006 Author Share Posted June 14, 2006 J'y avait pensé aussi pour le 's' Je ne sais pas pourquoi, je m'attendais à ce que Sandeman nous sorte une commande magique. Pareil que gauret et yoda, content de découvrir ça Link to post Share on other sites
theocrite Posted June 14, 2006 Author Share Posted June 14, 2006 et les autres options de paste sont faciles à implémenter... ils ont fait quoi quand ils ont programmé? En vrac : Le paste gère les caractères échapés, possède une gestion des erreurs (dans les fichiers lu et erreurs d'écriture), prend un nombre quelquoque de fichiers en arguments, permet de choisir un séparateur, permet de procéder en série au lieu de procéder en parallèle (rotation 90°). Pour la gestion des erreurs, il y a (entre autres) xputchar (char c) { if (putchar (c) < 0) write_error (); } Il fait un test en plus sur chaque caractère en output, donc forcément ça doit prendre un peu plus de temps. Link to post Share on other sites
gauret Posted June 25, 2006 Share Posted June 25, 2006 Allez, une nouvelle questions pour nos acharnés, extraite d'une histoire vraie. Mr G. (dont nous garderons l'anonymat) est en train de déployer Cacti sur un parc de serveurs FreeBSD. Pour cela, il faut installer SNMP sur ces serveurs. Les serveurs FreeBSD sont parfois un peu vieux, en version 4, mais l'arbre des ports a été régulièrement mis à jour pour disposer des dernieres versions des logiciels portés. Jusque là, tout va bien. Soudain, en faisant un "make install clean" dans /usr/ports/net-mgmt/net-snmp sur un vieux serveur FreeBSD 4.11, Mr G. constate une erreur de compilation ! C'est un patch qui s'est mal appliqué, et qui échoue avec l'erreur : "sed : option -i inconnue". Damn ! Le sed du système, donc de FreeBSD 4.11, ne gère pas encore l'option -i, et le Makefile des ports en a besoin parce que les ports sont à jour. Qu'à cela ne tienne, nous allons écrire un petit wrapper. Mais attention, le wrapper doit être compatible à 100% avec sed, et accepter la syntaxe d'appel de l'option -i (ex : sed -i.bak -e 's/truc/machin bidule/g' /chemin/vers/fichier) pour pouvoir être un remplaçant parfait ! Ah oui, et pour rigoler : vous me ferez ça en bash Calculatrices non autorisées (sauf si elles tournent sous un OS libre) Petite astuce, qui peut vous être utile ou pas : sous FreeBSD, les options des commandes sont forcément avant les arguments. Tout est un argument à partir du premier argument trouvé. Ex : ls -l /usr : OK ls /usr -l : Pas OK (ça cherche à faire un ls de /usr et de "-l") Link to post Share on other sites
yoda222 Posted June 25, 2006 Share Posted June 25, 2006 pas testé en profondeur (juste avec des echo ) #!/bin/bash SED=/usr/bin/sed option=0 argv="" for i in $*; do file=$i if [ $i = -i ]; then option=1 else argv="${argv} $i" fi done if [ ${option} = 0 ]; then ${SED} ${argv} else ${SED} ${argv} > /tmp/${file} mv /tmp/${file} ${file} fi Pas très joli joli d'ailleurs bug connu : - nom du fichier = -i (moui, enfin, bon, voila...) - sed de l'entrée standart avec -i comme option comportement différent du sed avec -i (qui répond "sed: impossible de lire -: Aucun fichier ou rértoire de ce type" ) - et bien sur les problèmes avec tmp et mv (si le fichier /tmp/${file} existe et pas écrasable, mauvais , et si le fichier "seddé" n'est pas écrasable, création d'un fichier temporaire indésiré dans /tmp) Link to post Share on other sites
lorinc Posted June 25, 2006 Share Posted June 25, 2006 et c'est pas plus simple de mettre sed à jour ? Link to post Share on other sites
tuXXX Posted June 25, 2006 Share Posted June 25, 2006 Bon c'est quand même un script conséquent... J'explique d'abord : sed comporte de nombreuses options qui ne sont pas des fichiers (notamment les scripts avec "-e", mais aussi quelques opotions...) Donc il faut trier tout ça et mettre de côté le nom des fichiers... Ensuite pour faire le backup quand on met -i sans extension, c'est pas trop dur (avec le numéro du processus...) Il faut gérer les fichiers avec espaces, et ça par contre c'est super chiant à faire... Donc là ça marche même avec des fichiers genre "-i" (et même des fichiers n'importe où tant qu'à faire) $ ./sedwrap intrus -e 's/foo/bar/' -i.truc -- -i fichier\ avec\ des\ espaces Bon donc voilà la bête : http://rafb.net/paste/results/qd6Orz16.html #!/bin/bash SED=sed args="" inplace="no" declare -a files #gestion des arguments : récupération des fichiers et de l'option "-i" while [ "$1" ] do case "$1" in --help|--version) $SED "$1" ;; -n|--quiet|--silent) args="$args $1";; --posix) args="$args $1";; -r|--regexp-extended) args="$args $1";; -s|--separate) args="$args $1";; -u|--unbuffered) args="$args $1";; -e) args="$args $1" shift args="$args '$1'" ;; *) if [ "${1:0:2}" = "-i" ] then inplace="yes" extension="${1/-i/}" elif [ "$1" = "--" ] then args="$args $1" shift while [ "$1" ] do files[${#files[@]}]="$1" shift done else files[${#files[@]}]="$1" fi esac shift done # exécution de sed sur tous les fichiers si option "-i" if [ "$inplace" = "yes" ] then for i in $(seq 0 $((${#files[@]} - 1))) do file=${files[$i]} if [ "$extension" ] then backup="$file$extension" else backup="$file.backup.$$" if [ -e "$backup" ] then echo "Error : $backup exists :(" 1>&2 exit 1 fi fi cp -- "$file" "$backup" eval "$SED $args '$backup'" > "$file" if [ "$?" != "0" ] then mv -- "$backup" "$file" exit "$?" fi if [ -z "$extension" ] then rm -- "$backup" fi done else eval "$SED $args" fi Link to post Share on other sites
theocrite Posted July 25, 2006 Author Share Posted July 25, 2006 Allez une question facile. Comment faire pour faire un cat à l'envers ? Par exemple cat test 5 4 3 2 1 à l'envers est comlètement ce fichier Je voudrais une façon de lire ça de bas en haut. Link to post Share on other sites
Poulpatine Posted July 25, 2006 Share Posted July 25, 2006 euh ... tac ( je suis sérieux ). Link to post Share on other sites
zoto Posted July 25, 2006 Share Posted July 25, 2006 Salut cat monfichier|sort -r par contre ça ne met pas en colone :) et là jen e vois pas :( a+ Link to post Share on other sites
tuXXX Posted July 25, 2006 Share Posted July 25, 2006 tac ( je suis sérieux ). +1 Link to post Share on other sites
theocrite Posted July 25, 2006 Author Share Posted July 25, 2006 Bah sort ça trie par ordre alpha, c'est pas le but Effectivement, cat à l'envers, ça fait tac Bon une autre simple aussi : Comment peut-on imprimer toutes les lignes d'un fichier en les précédant du numéro de ligne ? cat test Maître Corbeau, sur un arbre perché, Tenait en son bec un fromage. Maître Renard, par l'odeur alléché, Lui tint à peu près ce langage : "Hé ! bonjour, Monsieur du Corbeau. Que vous êtes joli ! que vous me semblez beau ! Sans mentir, si votre ramage Se rapporte à votre plumage, Vous êtes le Phénix des hôtes de ces bois." A ces mots le Corbeau ne se sent pas de joie; Et pour montrer sa belle voix, Il ouvre un large bec, laisse tomber sa proie. Le Renard s'en saisit, et dit : "Mon bon Monsieur, Apprenez que tout flatteur Vit aux dépens de celui qui l'écoute : Cette leçon vaut bien un fromage, sans doute. " Le Corbeau, honteux et confus, Jura, mais un peu tard, qu'on ne l'y prendrait plus. 1 Maître Corbeau, sur un arbre perché, 2 Tenait en son bec un fromage. 3 Maître Renard, par l'odeur alléché, 4 Lui tint à peu près ce langage : 5 "Hé ! bonjour, Monsieur du Corbeau. 6 Que vous êtes joli ! que vous me semblez beau ! 7 Sans mentir, si votre ramage 8 Se rapporte à votre plumage, 9 Vous êtes le Phénix des hôtes de ces bois." 10 A ces mots le Corbeau ne se sent pas de joie; 11 Et pour montrer sa belle voix, 12 Il ouvre un large bec, laisse tomber sa proie. 13 Le Renard s'en saisit, et dit : "Mon bon Monsieur, 14 Apprenez que tout flatteur 15 Vit aux dépens de celui qui l'écoute : 16 Cette leçon vaut bien un fromage, sans doute. " 17 Le Corbeau, honteux et confus, 18 Jura, mais un peu tard, qu'on ne l'y prendrait plus. Au moins 4 solutions dont trois en oneliners Link to post Share on other sites
tuXXX Posted July 25, 2006 Share Posted July 25, 2006 awk awk '{printf("%4d %s\n", NR,$0)}' fichier.txt sed sed -e '=' fichier.txt | sed -r -e 'N; s/^/ /; s/ *(.{4})\n/\1 /' bash i=0; cat fichier.txt | while read line; do ((i=i+1)); n=" $i"; echo "${n: -4} $line"; done ... je cherche d'autres solutions EDIT : perl perl -p -e '$_ = sprintf("% 4d %s", $., $_)' fichier.txt EDIT2 : modification du sed pour le simplifier Link to post Share on other sites
theocrite Posted July 25, 2006 Author Share Posted July 25, 2006 Ah j'avais pas pensé à awk Il y a (au moins) une autre solution aussi Link to post Share on other sites
tuXXX Posted July 26, 2006 Share Posted July 26, 2006 Ah! y'a nl aussi : nl -w 4 -s " " fichier.txt Pour rire, y'a grep : grep -n "^" fichier.txt Dans cet état c'est pas aussi joli, et si c'est pour utiliser sed/awk après ça sert à rien EDIT : et cat alors !? cat -n fichier.txt EDIT2 : en remarque, la version bash modifie les lignes qui démarrent ou finissent par des espaces ...et la version cat ne semble pas configurable pour avoir la même chose que les autres (ici 4 caractères pour le numéro de ligne et un espace de séparation). Vous pouvez vérifier, les versions awk, sed, perl et nl sont comme il faut Link to post Share on other sites
Sandeman Posted July 31, 2006 Share Posted July 31, 2006 A la demande générale (?) Imaginons que j'ai une mosaïque d'images : 9x9, représantant chacune un 81ème d'une image finale. par exemple des morceaux de carte d'un jeu en ligne comme "650 kilomètres" ... ... ... ... +--------+--------+--------+--------+... +--------+ | 11.jpg | 12.jpg | 13.jpg | 14.jpg | ... | 19.jpg| +--------+--------+--------+--------+... +--------+ | 21.jpg | 22.jpg | 23.jpg | 24.jpg | ... | 29.jpg| +--------+--------+--------+--------+... +--------+ : : : : : : : : +--------+--------+--------+--------+... +--------+ | 91.jpg | 92.jpg | 93.jpg | 94.jpg | ... | 99.jpg| +--------+--------+--------+--------+... +--------+ je fais un brutal wget couplé à un seq pour récupérer toutes les images : (de mémoire :) for i in seq `11 99` do wget http://www.650kilometres.com/images/map_5/$i.jpg done rm ?0.jpg Et maintenant je veux, en utilisant Imagemagick, en refaire une seule image (plus pratique :) genre le tout, non pas en 5 lignes, en 4 lignes ni même en 2 lignes ... en 1 ligne de commande. Et même plus fort : en 1 commande ... à vous de jouer ! (sinon essayez 650km c'est vraiment sympa ...) Link to post Share on other sites
nonas Posted August 1, 2006 Share Posted August 1, 2006 J'ai trouvé ! montage 650km_*.jpg -geometry 70x70 île.jpg C'est 'achement puissant ImageMagick quand même ! Jfais un tit script edit : for j in `seq 1 5` do mkdir île_$j cd île_$j for i in `seq 11 99` do wget http://www.650kilometres.com/images/map_$j/$i.jpg done rm ?0.jpg montage *.jpg -geometry 70x70 île_$j.jpg cd .. done Au moins le serveur aura une bonne raison de ramer ! Link to post Share on other sites
tuXXX Posted November 21, 2006 Share Posted November 21, 2006 J'ai vu que: echo toto > titi # crée un fichier titi contenant toto echo toto >> titi #met à la suite de titi un ligne contenant toto Maintenant comment rajouter une ligne en tout début ou à un certain endroit d'un fichier? Là c'est plus compliqué, il faut le faire en plusieurs fois avec un fichier intermédiaire. (Ou peut être qu'il y a des options dans les dernières versions de sed ou de perl, à voir). hehe ben en voilà une nouvelle bonne idée de script à faire Aussitôt dit, aussitôt fait . C'est en perl, au début j'ai fait avec des while, mais après j'ai découvert Tie::File . Bon en fait ça fait 2 lignes de code effectif, mais y'a de l'enrobage pour pouvoir l'utiliser dans n'importe quelle circonstances. #!/usr/bin/perl -w # Inserts input into file [at offset line, defaults to 0] use strict; use Tie::File; if($#ARGV<0){print "Usage : $0 file [line]\n";exit} tie my @file,'Tie::File',$ARGV[0] or die "\"$ARGV[0]\": $!"; my $i;$i=0 unless $i=$ARGV[1]; while(<STDIN>){splice @file,$i++,0,$_} EDIT : mince j'allais oublier l'exemple shell$ cat > file.txt 0 1 2 3 4 5 shell$ echo -e "voici deux\nlignes" | insert.pl file.txt 3 shell$ cat file.txt 0 1 2 voici deux lignes 3 4 5 shell$ Link to post Share on other sites
theocrite Posted November 22, 2006 Author Share Posted November 22, 2006 Beaucoup plus simple () une ligne de sed : cat replace.sh #! /bin/sh # usage : replace.sh num "pattern" file # requirements : gnu sed, sh LINE=$1 PATTERN=$2 FILE=$3 sed -i $LINE"s/^/$PATTERN\n/" $FILE sh replace.sh 3 "une ligne\nune autre" test cat test 1 2 une ligne une autre 3 4 5 6 7 8 9 10 Link to post Share on other sites
tuXXX Posted November 22, 2006 Share Posted November 22, 2006 Mais ça marche quand on utilise avec un pipe? Genre si on veut insérer la sortie de dmesg à la ligne 1000 de /var/log/messages (sinon c'est vrai qu'il fallait y penser) Link to post Share on other sites
Sandeman Posted November 15, 2007 Share Posted November 15, 2007 Re-up après presqu'1 an ... là c'est un collègue qui me la pose, j'admet que j'ai pas la réponse : c'est orienté KDE il ouvre konsole avec plusieurs onglet, pour se connecter sur différentes machines il aimerait que le nom de l'onglet colle avec la machine sur laquelle il se connecte. je suis sandeman@mamachine je fais ssh root@baga (ouais le jeu de mot ) l'onglet konsole devient root@baga un petit bout de code ... SESSION=`dcop $KONSOLE_DCOP currentSession` dcop `dcopclient $KONSOLE_DCOP` $SESSION renameSession "foobar" Link to post Share on other sites
lorinc Posted November 15, 2007 Share Posted November 15, 2007 j'ai une solution pas trop jolie, mais qui marchote : #!/bin/bash SESSION=$(dcop $KONSOLE_DCOP currentSession) dcop `dcopclient $KONSOLE_DCOP` $SESSION renameSession $* ssh $* dcop `dcopclient $KONSOLE_DCOP` $SESSION renameSession `whoami`@`hostname` que tu nommes kssh.sh, chmodé comme il faut, et tu t'en sers pour te connecter : kssh.sh user@machine (ou kssh tout crout en mettant l'alias qui va bien) la dernière ligne remet la bonne description au sortir du ssh. Le problème me semble difficilement solvable autrement, sachant que ce qui s'exécute dans le shell est inaccessible à dcop. Donc que je tape "pouetpouet" ou "ssh" c'est la même. Quand au prompt, c'est bash qui le gère. dcop n'a pas accès à ce qui s'affiche dans la konsole. si quelqu'un à mieux, je suis preneur. Link to post Share on other sites
tuXXX Posted November 16, 2007 Share Posted November 16, 2007 Moi je modifie le titre des terminaux depuis le shell du PC distant : if [ "$SSH_CLIENT" ] && [ "$SSH_CONNECTION" ] && [ "$SSH_TTY" ] then TITLE="[ssh:$(hostname)]" print -Pn "\e]0;${TITLE}\a" fi (avec zsh, à voir si ça marche pareil avec d'autres shells) Après, sous gnome-terminal automatiquement (les onglets ont le nom du titre de la fenêtre), sous konsole il suffit d'activer "Set tab title to match window title". Link to post Share on other sites
djuke Posted November 25, 2007 Share Posted November 25, 2007 Moi je modifie le titre des terminaux depuis le shell du PC distant : if [ "$SSH_CLIENT" ] && [ "$SSH_CONNECTION" ] && [ "$SSH_TTY" ] then TITLE="[ssh:$(hostname)]" print -Pn "\e]0;${TITLE}\a" fi (avec zsh, à voir si ça marche pareil avec d'autres shells) Après, sous gnome-terminal automatiquement (les onglets ont le nom du titre de la fenêtre), sous konsole il suffit d'activer "Set tab title to match window title". Pour les utilisateurs de bash, il faut signaler la variable PROMPT_COMMAND, qui est exécutée avant d'afficher le prompt. Donc, mettre ça dans son .bashrc: export PROMPT_COMMAND='echo -ne "33]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}7"' Plus d'infos ici: http://www.faqs.org/docs/Linux-mini/Xterm-Title.html Link to post Share on other sites
Recommended Posts
Archived
This topic is now archived and is closed to further replies.