GNU/Linux >> Tutoriels Linux >  >> Linux

Comment afficher les noms de fichiers qui contiennent deux caractères et dont l'un est c ?

Avec bash, définissez les paramètres glob afin que les correspondances manquantes ne déclenchent pas d'erreur :

shopt -u failglob  # avoid failure report (and discarding the whole line).
shopt -s nullglob  # remove (erase) non-matching globs.
ls ?c c?

Le point d'interrogation est un caractère global représentant un seul caractère. Puisque vous voulez des noms de fichiers à deux caractères, l'un d'eux doit être un c , et donc c'est soit le premier caractère, soit le dernier caractère.

Avec shopt -s dotglob cela afficherait également un fichier nommé .c .

S'il n'y a pas de fichiers correspondants, la définition de ces options du shell entraîne la suppression de tous les arguments, ce qui se traduit par un simple ls -- listant n'importe quoi/tout par défaut.

Utilisez ceci à la place :

shopt -s nullglob  ## drop any missing globs
set -- ?c c?       ## populate the [email protected] array with (any) matches
if [ $# -gt 0 ]    ## if there are some, list them
  ls -d "[email protected]"
fi

Je pense que la meilleure façon est d'utiliser find :

find . -type f -name '*c*' -name '??'

Cela effectuera une recherche récursive. Pour lister uniquement les fichiers du répertoire courant :

find . ! -name . -prune  -type f -name '*c*' -name '??'

Si les fichiers existent (et n'ont pas de caractères d'échappement comme \c ), vous pouvez utiliser un glob :

echo ?c c?

qui correspondra aux fichiers qui ont un caractère (? ) suivi d'un c ou qui ont un c suivi d'un caractère (? ).

Mais échouera avec les noms de fichiers qui commencent par un tiret comme -n ou -e ou avec des barres obliques inverses comme \c ou \n avec echo comme -e et -n sont spéciaux pour (certains shells) echo et \c ou \n serait interprété comme une séquence d'échappement (\c termine la sortie et \n imprime une nouvelle ligne, pas les caractères textuels \n dans certaines implémentations shell de echo et avec bash lorsque l'option shopt -s xpg_echo est réglé). D'autres applications ou utilitaires (comme ls ) aura d'autres options et peut échouer avec de nombreux autres caractères commençant par un tiret ou interpréter d'autres caractères d'échappement dans les noms de fichiers.

Listera également un fichier nommé cc deux fois.

  • Si un fichier peut commencer par un tiret (comme -n), utilisez :

    $ ls -d -- ?n 
    -n 
    

    Ou mieux :

    $ ls -d ./?n
    ./-n
    

Mises en garde

  • Glob ne correspond à aucun fichier.

    1. Si les fichiers n'existent pas, le glob ne sera pas développé et le glob sera imprimé dans sa forme d'origine.

      $ echo ?m m?
      ?m m?
      
    2. Sauf en zsh.

      $ zsh -c 'echo ?m m?'
      zsh:1: no matches found: ./m?
      

      Le shell se terminera avec une erreur.
      Ce comportement est contrôlé par le nomatch de Zsh option.

      $ zsh -c 'setopt +o nomatch; echo ?m m?'
      ?m m?
      

      Ou :

      $ zsh -c 'echo ?m(N) m?(N)'
      ?m m?
      

      Mais cela imprimera mm deux fois.

    3. Dans bash, vous pourriez obtenir un résultat similaire à zsh si l'option shell failglob est défini :

      $ bash -c 'shopt -s failglob; echo ?m m?'
      bash: no match: ?m
      

      Mais le script ne s'arrêtera pas, le shell ne se fermera pas. Eh bien, techniquement, la ligne où le glob est utilisé n'est pas exécutée davantage mais l'exécution reprend à la ligne de script suivante.

    4. En bash, vous pouvez définir l'option nullglob pour supprimer les globs qui ne correspondent pas :

      $ bash -c 'shopt -s nullglob; echo ?m m? done'
      done
      
  • Utilisation de ls (similaire à d'autres programmes)

    1. Avec les fichiers correspondants, il n'y aura pas de problème, mais les répertoires seront également mis en correspondance (et répertoriés) :

      $ ls ?c c?
      bc  cz  sc
      
      ac:
      hjk
      

      Mieux vaut utiliser -d avec ls (les répertoires seront inclus mais pas développés).

      $ ls -d ?c c?
      ac bc cz sc
      
    2. Les globs ne correspondent pas à un fichier (ou un répertoire)

      Alors ls signalera un échec

      $ ls ?m m?
      ls: cannot access '?m': No such file or directory
      

      D'autres programmes pourraient (probablement) ne pas faire des vérifications similaires.

    3. Utilisation de nullglob avec bash donnera une liste vide à ls, donc, il listera le contenu ou le pwd comme si seulement ls a été exécuté :

      $ ls ?m m?
      ac a.out cz 3 b sc ab bc
      

      Cela pourrait être évité en utilisant ./

      $ ls -d ./?m ./m?
      ls: cannot access './?m': No such file or directory
      ls: cannot access './m?': No such file or directory
      

Ou vous pouvez utiliser une regex de recherche (mais elle traversera les sous-répertoires avec prune manquant) (Notez que cela ne répétera pas un fichier appelé cc) :

    $ find . ! -name . -prune -regex '.*/\(.c\|c.\)'
    ./ac
    ./cc
    ./sc
    ./bc
    ./cz

Linux
  1. Grep Comment supprimer l'affichage d'un fichier non correspondant ?

  2. Comment vider (tronquer) un fichier sous Linux qui existe déjà et qui est protégé d'une manière ou d'une autre ?

  3. Comment joindre plusieurs lignes de noms de fichiers en une seule avec un délimiteur personnalisé ?

  4. Comment toucher un fichier et mkdir si nécessaire en une seule ligne

  5. Comment puis-je faire en sorte que 'diff -X' ignore des chemins spécifiques et non des noms de fichiers ?

Comprendre les chemins de fichiers et comment les utiliser sous Linux

Comment ajouter des commandes Linux à la file d'attente et les exécuter une par une

Comment rechercher et supprimer des fichiers contenant un texte spécifique dans leurs noms sous Linux

[Bash Tips] Comment cd et ls en une seule commande

[Bash Tips] Comment cp ou mv et cd en une seule commande

Comment supprimer les caractères (^M) d'un fichier sous Linux