web-dev-qa-db-fra.com

Comment répertorier les fichiers sans répertoires et filtrer par nom (options ls)

J'ai un répertoire appelé uploads. Il contient un tas de fichiers, ainsi que quelques sous-répertoires qui à leur tour contiennent des fichiers.

Existe-t-il un moyen (en une seule étape) de procéder comme suit:

  1. Énumérez UNIQUEMENT les fichiers dans le répertoire racine des téléchargements - je ne veux pas voir les noms des sous-dossiers ou leur contenu;

    et

  2. Ne répertoriez PAS les fichiers commençant par t_

Je connais le -d flag, mais ça ne me donne pas tout à fait ce que je veux.

45
EmmyS

Cela ressemble à un travail pour find.

  • Utilisation -maxdepth pour ne renvoyer que le répertoire courant, pas pour rechercher récursivement dans les sous-dossiers
  • Utilisation -type f pour ne renvoyer que des fichiers et non des répertoires ou des nœuds de périphérique ou quoi que ce soit d'autre
  • Utilisez une combinaison si -not et -name pour éviter les fichiers avec des noms dont vous ne voulez pas

Il pourrait se réunir comme ceci:

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'
55
Caleb

GNU ls (c'est-à-dire la commande ls sur les systèmes Linux non intégrés et Cygwin, également disponible sur certains autres unités) a une option pour masquer certains fichiers, en fonction de leurs noms. Il n'y a cependant aucun moyen d'ignorer les répertoires.

ls --hide='t_*' uploads

Une autre approche consiste à faire en sorte que votre Shell fasse la correspondance. Bash, ksh et zsh ont un modèle de négation !(t_*) pour correspondre à tous les fichiers sauf ceux correspondant à t*; en bash, cette fonctionnalité doit être activée avec shopt -s extglob et en zsh, elle doit être activée avec setopt ksh_glob. Zsh a également la syntaxe équivalente ^t_* Qui doit être activée avec setopt extended_glob. Cela n'ignore toujours pas les répertoires. Zsh a une fonctionnalité supplémentaire qui permet de faire correspondre les fichiers non seulement par nom mais aussi par métadonnées et plus: qualificatifs globaux . Ajoutez (.) À la fin d'une correspondance pour limiter les fichiers normaux. La négation ^ Fait partie de la syntaxe de correspondance des noms, donc ^t_*(.) signifie "tous les fichiers normaux ne correspondent pas t_*" Et non "tous les fichiers qui ne correspondent pas aux fichiers normaux t_* ”.

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

Si vous vous retrouvez sans outils avancés, vous pouvez le faire sur n'importe quel Unix avec find. Ce n'est pas le genre de chose que vous tapez habituellement sur la ligne de commande, mais c'est puissant et précis. Caleb a déjà montré comment le faire avec GNU find . L'option -maxdepth N'est pas portable; vous pouvez utiliser -Prune à la place, pour empêcher de manière portable find de se reproduire.

find uploads/* -type d -Prune -o \! -type f -name 't_*' -print

Remplacez -print Par -exec ls -lG -- {} + Pour exécuter ls avec vos options préférées sur les fichiers.

Toutes les commandes ci-dessus masquent les fichiers de points (c'est-à-dire les fichiers dont le nom commence par un .). Si vous souhaitez les afficher, passez -A À ls, ou ajoutez le qualificatif D glob dans zsh (ls uploads/^t_*(.D)). Avec find, vous pouvez utiliser une approche différente pour le rendre récurrent d'un niveau seulement (find ne traite pas spécialement les fichiers dot). Cela ne fonctionne pleinement que si vous exécutez find dans le répertoire en cours.

cd uploads && find . -name . -o -type d -Prune -o \! -type f -name 't_*' -print
ls -l /folder | grep ^- | awk '{print $9}'
10
Krayher
ls -l | grep -v ^d | grep name$

Si le problème de portabilité -maxdepth de find est un problème, vous pouvez utiliser:

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

Je ne suis pas un expert, mais je pense que cela devrait fonctionner. Je suppose que cela semble un peu énigmatique, mais si vous parlez mal, ce n'est vraiment pas le cas. $ NF pourrait être utilisé au lieu de 9 $. Vous pourriez également faire:

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

qui fait la même chose (mais peut-être moins efficacement que l'ancien ???).

En fait, après avoir pensé aux autres articles, on dirait

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

est un moyen encore plus court et plus clair.

Quelqu'un, s'il vous plaît, corrigez-moi si je me trompe. :-)

0
kkaszub

J'ai trouvé ces moyens courts:

ls -p uploads | grep -Ev '/'

ou

ls -pIt_* uploads | grep -v /
0
Radu Rădeanu

Permettez-moi de faire un essai en utilisant ls et des tuyaux:

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

disons que la dernière colonne est la 9e.

0
Y0NG