Outils personnels
Vous êtes ici : Accueil Linux Linux - Bon à savoir (ou FAQ) Le Shell ou les commandes Linux - Exemples
Se connecter


Mot de passe oublié ?
 

Le Shell ou les commandes Linux - Exemples

Par Freecrazy - Dernière modification 19/02/2014 14:15

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

Actions sur le document