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?
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 .
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
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
dansfind
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.
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
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.