web-dev-qa-db-fra.com

Imprimer la liste des fichiers d'un répertoire dans un fichier texte (mais pas le fichier texte lui-même) à partir du terminal

Je voudrais imprimer tous les noms de fichiers de chaque fichier d'un répertoire dans un fichier .txt.

Supposons que j'ai un répertoire avec 3 fichiers:

file1.txt
file2.txt
file3.txt

et j'ai essayé d'utiliser ls > output.txt.

Le problème, c’est que lorsque j’ouvre output.txt, je trouve cette liste:

file1.txt
file2.txt
file3.txt
output.txt

Existe-t-il un moyen d’éviter d’imprimer le nom du fichier sur lequel je redirige la sortie? Ou mieux existe-t-il une commande capable d’imprimer tous les noms de fichiers des fichiers d’un répertoire sauf un?

5
jackscorrow
printf '%s\n' * > output.txt

Notez que cela suppose qu’il n’existe pas de fichier output.txt préexistant - Si tel est le cas, supprimez-le d’abord.

  • printf '%s\n' * utilise globbing (extension du nom de fichier) pour imprimer de manière robuste les noms de tous les fichiers et sous-répertoires situés dans le répertoire en cours, ligne par ligne.

  • Globbing se produit avant output.txt est créé via la redirection de sortie > output.txt (ce qui se produit toujours avant que la commande ne soit exécuté , ce qui explique votre problème), son nom est not inclus dans la sortie.

  • Globbing évite également l'utilisation de ls, dont l'utilisation dans les scripts est généralement déconseillée

10
mklement0

En général, il n’est pas bon d’analyser la sortie de ls, en particulier lors de l’écriture de scripts de qualité production qui doivent être en règle pendant longtemps. Voir cette page pour savoir pourquoi: Ne pas analyser la sortie ls

Dans votre exemple, output.txt fait partie de la sortie dans ls > output.txt car Shell organise la redirection (vers output.txt) avant d'exécuter ls.

Le moyen le plus simple d’obtenir le bon comportement pour votre cas serait:

ls file*txt > output.txt # as long as you are looking for files named that way

ou, stockez la sortie dans un fichier caché (ou dans un fichier normal dans un autre répertoire) puis déplacez-la vers le dernier emplacement:

ls > .output.txt && mv .output.txt output.txt

Une solution plus générique serait d'utiliser grep -v:

ls | grep -vFx output.txt > output.txt

Ou, vous pouvez utiliser un tableau:

files=( "$(ls)" )
printf '%s\n' "${files[@]}" > output.txt
1
codeforester

ls a une option ignorer et nous pouvons également utiliser la commande find.

  • Utilisation de ls avec l'option ignore

    ls -I "output.txt" > output.txt
    ls --ignore "output.txt" > output.txt
    

-I, --ignore sont les mêmes. Cette option dit, comme dans la page de manuel, de ne pas répertorier les entrées implicites correspondant au modèle Shell. 

  • Utiliser find

    find \! -name "output.txt" > output.txt
    

L'option -name dans find permet de trouver les fichiers/répertoires dont le nom correspond au modèle. ! -name exclut le nom correspondant au modèle.

    find \! -name "output.txt" -printf '%P\n' > output.txt

% P supprime le chemin et ne donne que des noms.

0
derp

Le moyen le plus sûr, sans rien supposer sur les noms de fichiers, consiste à utiliser des tableaux bash (en mémoire) ou un fichier temporaire. Un fichier temporaire n'a pas besoin de mémoire, il peut donc être encore plus sûr. Quelque chose comme:

#!/bin/bash
tmp=$(tempfile)
ls > $tmp
mv $tmp output.txt
0
linuxfan

En utilisant les commandes ls et awk, vous pouvez obtenir le résultat correct. 

ls -ltr | awk '/txt/ {print $9}' > output.txt

Cela n'imprimera que les noms de fichiers.

0
Ramin Ismayilli