How to separate command output to individual lines
Instead of ill-advisedly putting ls
output in a variable and then echo
ing it, which removes all the colors, use
ls -a1
From man ls
-1 list one file per line. Avoid '\n' with -q or -b
I don't advise you do anything with the output of ls
, except display it :)
Use, for example, shell globs and a for
loop to do something with files...
shopt -s dotglob # to include hidden files*
for i in R/*; do echo "$i"; done
* this won't include the current directory .
or its parent ..
though
If the output of the command contains multiple lines, then quote your variables to preserve those newlines when echoing:
echo "$list"
Otherwise, the shell will expand and split the variable contents on whitespace (spaces, newlines, tabs) and those will be lost.
While putting it in quotes as @muru suggested will indeed do what you asked for, you might also want to consider using an array for this. For example:
IFS=$'\n' dirs=( $(find . -type d) )
The IFS=$'\n'
tells bash to only split the output on newline characcters o get each element of the array. Without it, it will split on spaces, so a file name with spaces.txt
would be 5 separate elements instead of one.
This approach will break if your file/directory names can contain newlines (\n
) though. It will save each line of the command's output as an element of the array.
Note that I also changed the old-style `command`
to $(command)
which is the preferred syntax.
You now have an array called $dirs
, each bof whose elements is a line of the output of the previous command. For example:
$ 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
Now, because of some bash strangeness (see here), you will need to reset IFS
back to the original value after doing this. So, either save it and reasign:
oldIFS="$IFS"
IFS=$'\n' dirs=( $(find . -type d) )
IFS="$oldIFS"
Or do it manually:
IFS=" "$'\t\n '
Alternatively, just close the current terminal. Your new one will have the original IFS set again.