Le Shell ou les commandes Linux - Exemples
On peut connaître quelques commandes, mais la vraie puissance du Shell est, comme tout langage de programmation, de pouvoir exécuter une suite de commandes pour obtenir le résultat voulu. Ici, vous trouverez des exemples de situations concrètes résolues par lignes de commande (éventuellement par script)
1 - Renommer des fichiers ... en masse
Bon, même en ligne de commande, vous savez certainement comment modifier le nom d'un seul fichier:
$ mv <ancien_nom> <nouveau_nom>
Mais vous vous êtes certainement retrouvé face à la nécessité de renommer plusieurs fichiers que ce soit l'appellation qui ne vous plaît pas ou des noms avec des caractères que Windows (ou plutôt ses Système de Fichiers: FAT, NTFS) n'apprécie guère. C'est ce dernier cas qui m'est arrivé hier: j'ai chargé mes cours vidéo (au cas où vous auriez loupé mon actu du 14 juin dernier je me suis inscrit à des MOOC - Massive Open Online Course - dont je suis devenu addict), et comme je veux y avoir accès sur plusieurs médias dont ma tablette (une genre 'noname') j'ai voulu les copier de mon PC sous LMDE (Linux Mint Debian Edition) sur la carte SD de ma tablette. Mais voilà mon '$ cp -r <dir_source> <dir_cible> me sort "impossible de créer le fichier .... Argument invalide"
En regardant de plus près mes fichiers, ils ressemblaient à ceci: "6 - 7 - 5-7 Learning Latent Models (15:57).mp4", et oui le ':' ne passe pas (même 'échappé' par \) !!
Modifier les fichiers un à un est long et fastidieux, alors qu'il existe une manière très simple de le faire (1)
$ cd <path du répertoire où se trouvent les fichiers à modifier> # cd = Change Directory
$ for i in *; do echo mv "$i" "${i//:/_}"; done
for i in *;
initie une boucle sur tous les fichiers (*), dans laquelle i, la variable se voit affectée le nom du fichier.
do <code> done
délimite le bloc de code exécuté à chaque boucle
echo
n'est là que pour vous renvoyer ce qui va être exécuté sans le faire. Si le résultat vous convient, enlevez-le !
mv "$i" "${i//:/_}";
l'instruction de renommage, vous aurez reconnu l'instruction move (mv) qui déplace le fichier d'origine "$i" dans le renommé auquel nous avons remplacé tous les 2 points //:
par un underscore /_
Les fichiers qui ne sont pas modifiés (ici ceux qui ne contiennent pas de ':') vont générer une erreur mais sans aucune incidence, ne vous étonnez pas d'un retour "verbeux".
A partir de là, les possibilités sont infinies. Par exemple je n'aimais pas les espaces encadrant les tirets (' - '), je voulais des underscores en lieu et place des espaces et enfin je voulais supprimer les ':' (sans les remplacer). Pour cela j'ai lancé:
$ for i in *; do mv "$i" "${i// - /-}"; done;
for i in *; do mv "$i" "${i// /_}"; done;
for i in *; do mv "$i" "${i//:/}"; done
Mes fichiers de forme "6 - 7 - 5-7 Learning Latent Models (15:57).mp4" ont pris la forme "6-7-5-7_Learning_Latent_Models_(1557).mp4".
Bon, c'est pas mal, mais ne peut-on pas tout passer en une seule fois ?
Si, mais il faut utiliser un autre programme qui permet les modifications multiples j'ai nommé sed qui est un 'éditeur de flux pour le filtrage et la transformation de texte' (cf. son manuel en français)
Pour reprendre l'exemple ci-dessus, la 'commande' devient:
$ for i in *; do mv "$i" "$(echo "$i" | sed -e 's/ - /-/g' -e 's/ /_/g' -e 's/://g')"; done
Plus court et pas plus compliqué lorsque l'on sait que:
echo "$i"
n'est là que pour générer le flux que l'on envoie par un pipe (|) à sed
-e
lance un traitement par sed
's/anciens caractères/nouveaux caractères/g'
s pour substitution et g pour garder le changement pour le traitement suivant.
A partir de ces exemples, vous devriez pouvoir sans trop de difficultés les adapter à votre besoin propre.
Si vous voulez approfondir l'utilisation de sed, jetez un œil sur le tuto de CCM.
Dernier point, vous aurez remarqué que je n'ai pas "échappé" avec '\' mes espaces, mon ':' et au besoin les parenthèses, etc. Pour moi (sous LMDE) cela a fonctionné mais je ne garantis pas sous d'autres OS surtout plus anciens.
(1) merci Pingouinux qui a donné la solution sur ce forum Ubuntu)
2 - Connaître le nombre de fichiers dans un répertoire
Source: Bash-Prompt-HOWTO (en anglais)
Vous connaissez certainement la commande 'ls' qui liste les fichiers d'un répertoire et ses options les plus classiques:
- -a pour obtenir en plus les fichiers commençant par un . (point)
- et -l pour en obtenir la description complète.
D'autres options, de 'filtre' notamment, existent mais je vous laisse les découvrir dans le 'man'. Mais il n'existe pas d'option pour connaître le nombre de fichiers listés, pourtant lorsque la liste est longue, cela peut être bien utile. La solution existe et elle est très simple:
$ ls | wc -l
wc affiche le nombre de lignes, de mots et de bytes dans un fichier, l'option -l ne retourne que le nombre de lignes.
Nota:
- ls -l | wc -l retourne 1 ligne de plus que la commande précédente, vous trouverez facilement pourquoi.
- n'oubliez pas que sous Linux tout est fichier, même un répertoire/dossier, ou encore un lien.
- n'oubliez pas que ls -l liste les fichiers en commençant par leur type (suivi de leurs droits en lecture/écriture/exécution): - <=> à un fichier ordinaire, d <=> à un directory (dossier), l <=> à un lien, (pour les autres définitions je vous renvoie au 'man') aussi pour ne compter que ce que l'on veut réellement, on peut filtrer avec grep, exemples:
// on ne compte que les répertoires $ ls -l | grep ^d | wc -l // on compte tous les fichiers sauf les liens (-v) $ ls -l | grep -v ^l | wc -l // on ne compte que les fichiers ordinaires en évitant le + 1 évoqué précédemment et lié à l'affichage d'une ligne 'total <nombre de blocs>' $ ls -l | grep ^- | wc -l
3 - Remplacer un mot dans un fichier
Un exemple: vous avez votre Debian Squeeze à upgrader en Wheezy et une étape est de changer les lignes du fichier /etc/apt/sources.list contenant squeeze par les mêmes lignes contenant wheezy. Pour cela rien de plus simple avec la commande sed :
# sed -i -e "s/squeeze/wheezy/g" /etc/apt/sources.list
Nota:
- nous sommes ici en administrateur/root (invite = #) car le fichier est un fichier système
- l'option -i est là pour l'interactivité (changements pris en compte dans le fichier)
source: cet article sur tux-planet