list=`ls -a R*`
echo $list
Dans un script Shell, cette commande echo répertorie tous les fichiers du répertoire en cours commençant par R, mais sur une ligne. Comment puis-je imprimer chaque article sur une ligne?
J'ai besoin d'une commande générique pour tous les scénarios se produisant avec ls
, du
, find -type -d
, etc.
Si la sortie de la commande contient plusieurs lignes, citez vos variables pour conserver ces nouvelles lignes lors de l'écho:
echo "$list"
Sinon, le Shell développera et divisera le contenu de la variable sur des espaces (espaces, nouvelles lignes, onglets) et ceux-ci seront perdus.
Au lieu de mettre à tort la sortie de ls
dans une variable, puis de echo
ing, qui supprime toutes les couleurs, utilisez
ls -a1
De man ls
-1 list one file per line. Avoid '\n' with -q or -b
Je ne vous conseille rien de faire avec la sortie de ls
, sauf l'afficher :)
Utilisez par exemple Shell globs et une boucle for
pour créer quelque chose avec les fichiers ...
shopt -s dotglob # to include hidden files*
for i in R/*; do echo "$i"; done
* ceci n'inclut pas le répertoire actuel .
ni son parent ..
si
Tout en le mettant entre guillemets sous la forme @muru suggéré fera effectivement ce que vous avez demandé, vous pouvez également envisager d'utiliser un tableau pour cela. Par exemple:
IFS=$'\n' dirs=( $(find . -type d) )
Le IFS=$'\n'
indique à bash de ne scinder que la sortie sur les caractères de nouvelle ligne pour obtenir chaque élément du tableau. Sans lui, il se divisera en espaces, donc a file name with spaces.txt
serait composé de 5 éléments distincts au lieu d'un. Cette approche sera interrompue si vos noms de fichier/répertoire peuvent contenir des nouvelles lignes (\n
). Cela enregistrera chaque ligne de la sortie de la commande en tant qu'élément du tableau.
Notez que j'ai également changé l'ancien style `command`
en $(command)
, qui est la syntaxe préférée.
Vous avez maintenant un tableau appelé $dirs
, chaque bof dont les éléments est une ligne de la sortie de la commande précédente. Par exemple:
$ find . -type d
.
./olad
./ho
./ha
./ads
./bar
./ga
./da
$ IFS=$'\n' dirs=( $(find . -type d) )
$ for d in "${dirs[@]}"; do
echo "DIR: $d"
done
DIR: .
DIR: ./olad
DIR: ./ho
DIR: ./ha
DIR: ./ads
DIR: ./bar
DIR: ./ga
DIR: ./da
Maintenant, à cause d'une certaine étrangeté bash (voir here ), vous devrez réinitialiser IFS
à la valeur d'origine après avoir effectué cette opération. Alors, sauvegardez-le et modifiez-le:
oldIFS="$IFS"
IFS=$'\n' dirs=( $(find . -type d) )
IFS="$oldIFS"
Ou faites le manuellement:
IFS=" "$'\t\n '
Sinon, fermez simplement le terminal actuel. Votre nouvel appareil aura à nouveau le réglage IFS d'origine.