web-dev-qa-db-fra.com

Parcourez un dossier et répertoriez les fichiers

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?

14
Raji

Utilisez basename pour supprimer le premier chemin des fichiers:

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

Mais pourquoi pas:

( cd sample; ls )
32
DopeGhoti

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

3
Eric Renouf

É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
2
bb_referee

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 {} \;
1
ctx