web-dev-qa-db-fra.com

Comment obtenir la liste des fichiers d'un répertoire dans un script Shell?

J'essaie d'obtenir le contenu d'un répertoire à l'aide d'un script Shell.

Mon script est:

for entry in `ls $search_dir`; do
    echo $entry
done

$search_dir est un chemin relatif. Cependant, $search_dir contient de nombreux fichiers avec des noms d'espaces blancs. Dans ce cas, ce script ne s'exécute pas comme prévu.

Je sais que je pourrais utiliser for entry in *, mais cela ne fonctionnerait que pour mon répertoire actuel.

Je sais que je peux accéder à ce répertoire, utiliser for entry in *, puis revenir en arrière, mais ma situation particulière m'empêche de le faire.

J'ai deux chemins relatifs $search_dir et $work_dir, et je dois travailler sur les deux simultanément, en les lisant pour créer/supprimer des fichiers dessus, etc.

Alors qu'est-ce que je fais maintenant?

PS: J'utilise bash.

110
jrharshath
for entry in "$search_dir"/*
do
  echo "$entry"
done
203

Les autres réponses sont excellentes et répondent à votre question, mais c’est le résultat principal de Google pour "bash obtenir la liste des fichiers dans le répertoire" (que je cherchais pour enregistrer une liste de fichiers). répondre à ce problème:

ls $search_path > filename.txt

Si vous voulez seulement un certain type (par exemple, n'importe quel fichier .txt):

ls $search_path | grep *.txt > filename.txt

Notez que $ search_path est facultatif; ls> nomfichier.txt fera le répertoire courant.

19
tegan
for entry in "$search_dir"/* "$work_dir"/*
do
  if [ -f "$entry" ];then
    echo "$entry"
  fi
done
17
ghostdog74

C’est une façon de le faire où la syntaxe est plus simple à comprendre pour moi:

yourfilenames=`ls ./*.txt`
for eachfile in $yourfilenames
do
   echo $eachfile
done

./ est le répertoire de travail actuel mais peut être remplacé par n'importe quel chemin
*.txt renvoie rien.txt
Vous pouvez vérifier facilement ce qui sera répertorié en tapant la commande ls directement dans le terminal.

En gros, vous créez une variable yourfilenames contenant tout ce que la commande de liste renvoie sous forme d'élément séparé, puis vous la parcourez. La boucle crée une variable temporaire eachfile qui contient un seul élément de la variable en cours de boucle, dans ce cas un nom de fichier. Ce n'est pas nécessairement meilleur que les autres réponses, mais je le trouve intuitif car je connais déjà bien la commande ls et la syntaxe de la boucle for. 

11
rrr
find "${search_dir}" "${work_dir}" -mindepth 1 -maxdepth 1 -type f -print0 | xargs -0 -I {} echo "{}"
10
November Yankee
$ pwd; ls -l
/home/victoria/test
total 12
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  a
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  b
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  c
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:32 'c d'
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:31  d
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32  dir_a
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32  dir_b
-rw-r--r-- 1 victoria victoria    0 Apr 23 11:32 'e; f'

$ find . -type f
./c
./b
./a
./d
./c d
./e; f

$ find . -type f | sed 's/^\.\///g' | sort
a
b
c
c d
d
e; f

$ find . -type f | sed 's/^\.\///g' | sort > tmp

$ cat tmp
a
b
c
c d
d
e; f

Variations

$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

Remarques:

  • .: dossier actuel
  • supprimer -maxdepth 1 pour effectuer une recherche récursive
  • -type f: recherche de fichiers et non de répertoires (d)
  • -not -path '*/\.*': ne pas renvoyer .hidden_files
  • sed 's/^\.\///g': supprime le ./ ajouté par défaut de la liste des résultats
1
Victoria Stuart

La réponse acceptée ne renverra pas les fichiers avec le préfixe. Pour faire cela utiliser

for entry in "$search_dir"/* "$search_dir"/.[!.]* "$search_dir"/..?*
do
  echo "$entry"
done
0
TrevTheDev

Voici une autre façon de répertorier les fichiers dans un répertoire (en utilisant un outil différent, moins efficace que certaines des autres réponses).

cd "search_dir"
for [ z in `echo *` ]; do
    echo "$z"
done

echo * Affiche tous les fichiers du répertoire en cours. La boucle for parcourt chaque nom de fichier et s’imprime sur stdout.

De plus, si vous recherchez des répertoires à l'intérieur du répertoire, placez-les à l'intérieur de la boucle for:

if [ test -d $z ]; then
    echo "$z is a directory"
fi

test -d vérifie si le fichier est un répertoire.

0
SnoopDogg

Sur la version Linux, je travaille avec (x86_64 GNU/Linux):

for entry in $search_dir/*
do
  echo $entry
done
0
Andrushenko Alexander