Parcourez un dossier et répertoriez les fichiers

14

J'ai un dossier nommé «échantillon» et il contient 3 fichiers. Je veux écrire un script shell qui lira ces fichiers dans le dossier d'exemples et le publiera sur un site HTTP en utilisant curl.

J'ai écrit ce qui suit pour répertorier les fichiers dans le dossier:

for dir in sample/*; do
        echo $dir;
        done

Mais cela me donne la sortie suivante:

sample/log

sample/clk

sample/demo

Il y joint le dossier parent. Je veux la sortie comme suit (sans le nom du dossier parent)

log

clk

demo

Comment puis-je faire cela?

Raji
la source
1
utilisez d'abord 'cd'. Si vous avez besoin de le "boucler", vous devez toujours entrer dans le répertoire. Vous pouvez également utiliser echo ${dir##*/}pour décoller le chemin.
Utopic eexpress

Réponses:

32

Utilisez basenamepour supprimer le premier chemin des fichiers:

for file in sample/*; do
    echo "$(basename "$file")"
done

Mais pourquoi pas:

( cd sample; ls )
DopeGhoti
la source
3

En supposant que votre shell le supporte, vous pouvez utiliser l'expansion des paramètres

for path in sample/*; do
    printf -- '%s\n' "${path##*/}"
done

ou vous pouvez simplement passer à ce répertoire et y faire la liste

Eric Renouf
la source
1
Le --n'est pas nécessaire ici. Le premier argument est une chaîne fixe sans tirets.
Kusalananda
Il ${parameter##pattern}est également pris en charge par tous les shells POSIX.
Kusalananda
2

Étant donné que les systèmes * nix permettent à presque tous les caractères de faire partie d'un nom de fichier (y compris les espaces, les sauts de ligne, les virgules, les symboles de canal, etc.), vous ne devez jamais analyser la sortie de la commande "ls" dans un script shell. Ce n'est pas fiable. Voir Pourquoi vous ne devriez pas analyser la sortie de ls .

Utilisez "rechercher" pour créer une liste de fichiers. Si vous utilisez Bash, vous pouvez insérer la sortie de "find" dans un tableau. Exemple ci-dessous, avec la mise en garde que j'ai utilisé une commande "curl" qui ne fonctionne pas!

searchDir="sample/"
oldFiles=()
while IFS= read -r -d $'\0' foundFile; do
    oldFiles+=("$foundFile")
done < <(find "$searchDir" -maxdepth 1 -type f -print0 2> /dev/null)

if [[ ${#oldFiles[@]} -ne 0 ]]; then
    for file in "${oldFiles[@]}"; do
        curl -F data=@"$file" UPLOAD_ADDRESS
    done
fi
bb_referee
la source
Quel est le répertoire ici? $ '\ 0'? Je veux passer un répertoire qui est dans une variable ...
Soylent Graham
searchDir est la variable de répertoire. "-d $ '\ 0'" définit le délimiteur de la commande de lecture sur null.
bb_referee
Comment puis-je réaliser la même chose dans un shell sh? J'utilise #! / Bin / sh
Ayusman
1

Cela dépend de ce que vous voulez faire avec les répertoires.

Pour simplement imprimer le nom, sans vérifier s'il s'agit d'un répertoire, vous pouvez utiliser ls:

ls -1 sample

Mieux vaut trouver, car vous pouvez utiliser des filtres:

find sample -type d -maxdepth 1 -printf '%f\n'

Si vous souhaitez exécuter des commandes sur les fichiers, vous devez utiliser find et non une boucle for:

find sample -type d -maxdepth 1 -exec basename {} \;
ctx
la source