Bash: trucs et astuces : Différence entre versions
m (→Conversions) |
m |
||
| Ligne 66 : | Ligne 66 : | ||
==== split chaine de caracteres: ==== | ==== split chaine de caracteres: ==== | ||
1)IFS: | 1)IFS: | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
OIFS=$IFS | OIFS=$IFS | ||
string="ABCDE-123456" | string="ABCDE-123456" | ||
| Ligne 73 : | Ligne 74 : | ||
echo $2 # >>> 123456 | echo $2 # >>> 123456 | ||
IFS=$OIFS # restituer le séparateur originel | IFS=$OIFS # restituer le séparateur originel | ||
| + | </syntaxhighlight> | ||
2) récupérer le début ou la fin (ici separateur = ' ' ) | 2) récupérer le début ou la fin (ici separateur = ' ' ) | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
line="myhost 192.168.1.145 abcdefg 123456" | line="myhost 192.168.1.145 abcdefg 123456" | ||
# enlever le dernier champ | # enlever le dernier champ | ||
| − | + | echo ${line% *} | |
| − | myhost 192.168.1.145 abcdefg | + | # -> myhost 192.168.1.145 abcdefg |
# conserver le premier champ | # conserver le premier champ | ||
| − | + | echo ${line%% *} | |
| − | myhost | + | # -> myhost |
# enlever le premier champ | # enlever le premier champ | ||
| − | + | echo ${line#* } | |
| − | 192.168.1.145 abcdefg 123456 | + | # -> 192.168.1.145 abcdefg 123456 |
# conserver le dernier champ | # conserver le dernier champ | ||
| − | + | echo ${line##* } | |
| − | 123456 | + | # -> 123456 |
| + | </syntaxhighlight> | ||
3) affecter les différents termes d'une ligne (cf IFS) à un tableau | 3) affecter les différents termes d'une ligne (cf IFS) à un tableau | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
line="myhost 192.168.1.145 is a good host" | line="myhost 192.168.1.145 is a good host" | ||
| − | + | termes=($line) | |
| − | + | echo ${termes[0]} | |
| − | myhost | + | # -> myhost |
| − | + | echo ${termes[4]} | |
| − | good | + | # -> good |
| + | </syntaxhighlight> | ||
==== substring ==== | ==== substring ==== | ||
Par exemple: | Par exemple: | ||
| − | + | <syntaxhighlight lang="bash" line='line'> | |
| − | + | date=2017-01-12 | |
| − | + | echo ${date:5:2} | |
| − | + | # -> 01 | |
| + | </syntaxhighlight> | ||
=== Utiliser les expressions régulières directement dans le shell === | === Utiliser les expressions régulières directement dans le shell === | ||
Avec l'opérateur =~ , par exemple: | Avec l'opérateur =~ , par exemple: | ||
| − | + | <syntaxhighlight lang="bash" line='line'> | |
| + | regex="([0-9]+)[[:space:]](.*)" | ||
file="02 Rumour Has It.wma" | file="02 Rumour Has It.wma" | ||
if [[ $file =~ $regex ]]; then | if [[ $file =~ $regex ]]; then | ||
echo "matched:(${BASH_REMATCH[1]}) -> ${BASH_REMATCH[2]}" | echo "matched:(${BASH_REMATCH[1]}) -> ${BASH_REMATCH[2]}" | ||
fi | fi | ||
| − | </ | + | </syntaxhighlight> |
=== récupérer le resultat d'une commande dans un tableau, ligne à ligne === | === récupérer le resultat d'une commande dans un tableau, ligne à ligne === | ||
1) IFS: | 1) IFS: | ||
| − | + | <syntaxhighlight lang="bash" line='line'> | |
| − | + | IFS=$'\r\n' | |
| − | + | aa=($(grep blabla /pathtofile)) | |
| − | + | echo ${aa[0]} | |
| + | # -> ici ma premiere ligne. | ||
| + | </syntaxhighlight> | ||
manipuler le tableau: | manipuler le tableau: | ||
| − | for str in "${aa[@]}";do echo $str | + | <syntaxhighlight lang="bash" line='line'> |
| + | for str in "${aa[@]}";do | ||
| + | echo $str | ||
| + | done | ||
| + | </syntaxhighlight> | ||
2) read: il faut passer par un fichier intermédiaire | 2) read: il faut passer par un fichier intermédiaire | ||
| − | + | <syntaxhighlight lang="bash" line='line'> | |
| − | + | grep blabla /pathtofile > /tmp/out | |
| + | while read str; do | ||
| + | echo $str | ||
| + | done < /tmp/out | ||
| + | </syntaxhighlight> | ||
=== manipuler des variables === | === manipuler des variables === | ||
# variable avec valeur par defaut | # variable avec valeur par defaut | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
if [ ${var:=n} = "y" ]; then ... | if [ ${var:=n} = "y" ]; then ... | ||
| − | => affecte 'n' par défaut à $var. | + | # => affecte 'n' par défaut à $var. |
| + | </syntaxhighlight> | ||
=== manipuler les lignes d'un fichier: exemple conversion d'un dossier mp3 => wav === | === manipuler les lignes d'un fichier: exemple conversion d'un dossier mp3 => wav === | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
# chercher lister les fichiers mp3 | # chercher lister les fichiers mp3 | ||
find . -name "*.mp3" > /tmp/lst | find . -name "*.mp3" > /tmp/lst | ||
| Ligne 149 : | Ligne 170 : | ||
let i=i+1; | let i=i+1; | ||
done | done | ||
| + | </syntaxhighlight> | ||
== Modifier quelques comportements avec shopt == | == Modifier quelques comportements avec shopt == | ||
| Ligne 155 : | Ligne 177 : | ||
Pour utiliser des alias distants en SSH, ajouter dans .bashrc de l'utilisateur distant: | Pour utiliser des alias distants en SSH, ajouter dans .bashrc de l'utilisateur distant: | ||
| + | <syntaxhighlight lang="bash" line='line'> | ||
if [ -z "$PS1" ]; then | if [ -z "$PS1" ]; then | ||
shopt -s expand_aliases | shopt -s expand_aliases | ||
fi | fi | ||
| + | </syntaxhighlight> | ||
=== avec cdable_vars interpréter les variables pour la commande 'cd' === | === avec cdable_vars interpréter les variables pour la commande 'cd' === | ||
Version du 28 juillet 2018 à 15:48
Sommaire
- 1 Fonctions utiles
- 1.1 Conversions
- 1.2 manipuler des chaines de caractères
- 1.3 Utiliser les expressions régulières directement dans le shell
- 1.4 récupérer le resultat d'une commande dans un tableau, ligne à ligne
- 1.5 manipuler des variables
- 1.6 manipuler les lignes d'un fichier: exemple conversion d'un dossier mp3 => wav
- 2 Modifier quelques comportements avec shopt
- 3 Comportement / syntaxe bash
- 4 Manipuler l'historique
Fonctions utiles
Conversions
conversion netmask => cidr
Exemple: mask2cidr 255.255.128.0 --> 17
1 # suppose qu'il n'y a plus de "255." après un octet non-255
2 mask2cidr ()
3 {
4 local x=${1##*255.}
5 set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
6 x=${1%%$3*}
7 echo $(( $2 + (${#x}/4) ))
8 }
conversion cidr => netmask
Exemple: cidr2mask 17 --> 255.255.128.0
1 cidr2mask ()
2 {
3 set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
4 [ $1 -gt 1 ] && shift $1 || shift
5 echo ${1-0}.${2-0}.${3-0}.${4-0}
6 }
expansion IPv6
Exemple: expand_ip6 fe80::68c8:c7b1:3199:f4b --> fe80:0000:0000:0000:68c8:c7b1:3199:0f4b
1 expand_ip6() {
2 ip6=$1
3 IFS=: ff=($ip6); unset IFS
4 res=""
5 let ix=0
6 nf=${#ff[*]}
7 while [ $ix -lt $nf ]; do
8 it=${ff[ix]}
9 if [ ${#it} -gt 0 ]; then
10 let n=4-${#it};
11 while [ $n -gt 0 ]; do it="0${it}"; let n=n-1;done ;
12 else
13 let n=8-$nf;
14 it="0000";
15 while [ $n -gt 0 ]; do it="${it}:0000"; let n=n-1;done ;
16 fi;
17 if [ -z "$res" ];then
18 res=$it;
19 else
20 res="${res}:${it}";
21 fi
22 let ix=ix+1
23 done
24 echo $res
25 }
compression IPv6
Exemple: compress_ip6 fe80:0000:0000:0000:68c8:c7b1:3199:0f4b --> fe80::68c8:c7b1:3199:f4b
1 compress_ip6() {
2 ip6=$1
3 echo $ip6 | sed -r -e 's/:0+/:0/g' -e 's/:(0:){2,8}/::/' -e 's/:0([1-9a-f])/:\1/g'
4 }
manipuler des chaines de caractères
split chaine de caracteres:
1)IFS:
1 OIFS=$IFS
2 string="ABCDE-123456"
3 IFS=- # use "local IFS=-" inside the function
4 set $string
5 echo $1 # >>> ABCDE
6 echo $2 # >>> 123456
7 IFS=$OIFS # restituer le séparateur originel
2) récupérer le début ou la fin (ici separateur = ' ' )
1 line="myhost 192.168.1.145 abcdefg 123456"
2
3 # enlever le dernier champ
4 echo ${line% *}
5 # -> myhost 192.168.1.145 abcdefg
6
7 # conserver le premier champ
8 echo ${line%% *}
9 # -> myhost
10
11 # enlever le premier champ
12 echo ${line#* }
13 # -> 192.168.1.145 abcdefg 123456
14
15 # conserver le dernier champ
16 echo ${line##* }
17 # -> 123456
3) affecter les différents termes d'une ligne (cf IFS) à un tableau
1 line="myhost 192.168.1.145 is a good host"
2 termes=($line)
3 echo ${termes[0]}
4 # -> myhost
5 echo ${termes[4]}
6 # -> good
substring
Par exemple:
1 date=2017-01-12
2 echo ${date:5:2}
3 # -> 01
Utiliser les expressions régulières directement dans le shell
Avec l'opérateur =~ , par exemple:
1 regex="([0-9]+)[[:space:]](.*)"
2 file="02 Rumour Has It.wma"
3 if [[ $file =~ $regex ]]; then
4 echo "matched:(${BASH_REMATCH[1]}) -> ${BASH_REMATCH[2]}"
5 fi
récupérer le resultat d'une commande dans un tableau, ligne à ligne
1) IFS:
1 IFS=$'\r\n'
2 aa=($(grep blabla /pathtofile))
3 echo ${aa[0]}
4 # -> ici ma premiere ligne.
manipuler le tableau:
1 for str in "${aa[@]}";do
2 echo $str
3 done
2) read: il faut passer par un fichier intermédiaire
1 grep blabla /pathtofile > /tmp/out
2 while read str; do
3 echo $str
4 done < /tmp/out
manipuler des variables
# variable avec valeur par defaut
1 if [ ${var:=n} = "y" ]; then ...
2 # => affecte 'n' par défaut à $var.
manipuler les lignes d'un fichier: exemple conversion d'un dossier mp3 => wav
1 # chercher lister les fichiers mp3
2 find . -name "*.mp3" > /tmp/lst
3 # lire la liste dans un tableau (1 enregistrement par ligne)
4 IFS=$'\n' read -d '' -r -a files < /tmp/lst
5 while [ $i -lt ${#files[@]} ]; do
6 fout=` echo ${files[$i]} | sed "s/.mp3/.wav/"`;
7 lame --decode "${files[$i]}" "../wav/$fout";
8 let i=i+1;
9 done
Modifier quelques comportements avec shopt
SSH et les alias
Les alias ne sont développés qu'avec les shells interactifs sauf si l'option expand_aliases du shell est activée par la commande shopt. Pour utiliser des alias distants en SSH, ajouter dans .bashrc de l'utilisateur distant:
1 if [ -z "$PS1" ]; then
2 shopt -s expand_aliases
3 fi
avec cdable_vars interpréter les variables pour la commande 'cd'
Si cette option est active, un argument de la commande interne cd qui n'est pas un répertoire est supposé être un nom de variable dont la valeur est le répertoire visé. Exemple:
$ shopt -s cdable_vars $ vms=/home/VMimages $ cd vms /home/VMimages
avec nocaseglob ignorer la casse pour développer les noms de fichiers
Si cette option est active, bash traite les noms de fichiers sans différences minuscules/majuscules lors du développement des noms de fichiers
$ shopt -s nocaseglob $ ls cis* CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.4.0-oval.xml CIS_Red_Hat_Enterprise_Linux_6_Benchmark_v1.4.0-xccdf.xml
Comportement / syntaxe bash
Grouper des commandes
- avec () les commandes placées dans la liste entre parenthèses sont exécutées dans un sous-shell. Il n'y a pas persistence dans le shell courant des variables manipulées dans ces commandes.
- avec {} les commandes placées entre accolades sont exécutées dans le contexte de shell courant. Le point virgule séparant les commandes est obligatoire sur la dernière, ainsi que les espaces autour de début et fin de bloc. D'éventuelles redirections peuvent être appliquées au bloc de commandes. Par exemple, lire un fichier dans une variable, et éviter les messages d'erreur:
{ var=$(<"$file"); } 2>/dev/null;
Manipuler l'historique
- Répéter la dernière commande : !!
- Répéter la dernière commande commançant par un motif:
$ !echo echo Bash Shortcuts Bash Shortcuts
et avec ":p" afficher la dernière commande commançant par un motif sans l'exécuter (mais l'exécuter ensuite avec !!):
$ echo Bash Shortcuts Bash Shortcuts $ wc -m /etc/bash_completion 45 /etc/bash_completion $ !echo:p echo Bash Shortcuts $ !! echo Bash Shortcuts Bash Shortcuts
- Rappeler les arguments de la dernière commande (tous : !* , le premier: !^ , le dernier: !$ ).
$ echo First Bash Shortcuts arg is not last First Bash Shortcuts arg is not last $ touch !* touch First Bash Shortcuts arg is not last $ ls First Bash Shortcuts arg is not last ... $ rm First Bash Shortcuts arg is not last $ echo !^ First $ echo First Bash Shortcuts arg is not last $ touch !* touch last
- Rappeler la dernière commande avec substitution d'une partie
$ echo this is our args this is our args $ ^our args^my last word^ echo this is my last word this is my last word
- Rappeler une commande avec substitution
$ localectl list-keymaps |grep "^fr" ... $ ls ... $ !locale:s/fr/us/ localectl list-keymaps |grep "^us" us us-acentos ...
- Rappeler des commandes avec leur position dans l'historique
$ history 1018 find /usr/share/doc/ -name bonding.txt 1019 echo this is my last word 1020 localectl list-keymaps |grep "^us" 1021 history $ !-3 echo this is my last word this is my last word $ !1018 find /usr/share/doc/ -name bonding.txt /usr/share/doc/kernel-doc-3.10.0/Documentation/networking/bonding.txt