Assign the result of a multiline command to a variable

Hi,
I have the following command that lists all the .o files from all the directories except of vwin (which I don't want it)

for i in `ls -d */*.o|awk '$0 !~ "vwin"'`; do echo $i; done

The result is something like that

dir1/file1.o
dir1/file2.o
dir2/file3.o
etc.

So, I want to create a variable which will have the following value:

var1="dir1/file1.o dir1/file2.o dir2/file3.o"

I tried first to do that

echo `for i in `ls -d */*.o|awk '$0 !~ "vwin"'`; do echo $i; done`

in order to have the multiple lines to one. Unfortunately it doesn't work because of the ";" (I guess).

Can someone help?
Thanks

That command is extremely redundant. You do not need to cram awk's output into a for-loop to make it print. Leave it out of the loop completely.

ls -d */*.o|awk '$0 !~ "vwin"

It didn't work because you can't nest backticks in that way, it will take the second ` to be the end of the first, not an inner set. For this reason modern shells use $( ) instead of backticks since they nest without trouble. You don't need to nest anything, though.

So your command, with the useless loop removed, boils down to:

VAR=$(ls -d */*.o|awk '!/vwin/')

It is more versatile to store the multi-line in VAR .
So you have the option of echo "$VAR"
or on-the-fly folding with (set -f; echo $VAR) or echo "$VAR" | paste -sd " " -

OK then:

VAR="$(ls -d */*.o|awk '!/vwin/')"

The quotes are not useful. Your previous post was already multiline.

putting a list of files in a string variable assumes the files won't have whitespace in them and this can break things. ideally you'd process them more carefully. if you're using bash, there are arrays and extglob.

shopt -s extglob
files=( */!(*vwin*).o )

for f in "${files[@]}"; do
   ...
done
var=`ls -d */*.o | grep -v vwin`

Now var has the value of all the *.o files

I am not sure it preserved literal newlines, though. It may have only preserved them as spaces.

Thank you all of you, guys.
You helped me a lot.

MadeInGermany is correct; the quotes are a no-op. Double quotes only prevent expansions which can produce multiple words, i.e. field splitting and pathname expansion. However, this type of expansion is not allowed on text which is to be assigned to a variable (the same is true of the word in a case word in ... esac statement).

Command substitution will strip any trailing newlines, but this cannot be prevented and has nothing to do with quoting.

Regards,
Alister

1 Like