Reputation: 11
I've been trying to take the output of ls /Applications/
and put each line into an array, then do a for loop of the array.
#!/bin/bash
ls /Applications | grep Adobe > adobeapps
adobearray=( 'cat "adobeapps" ')
for i in "${adobearray[@]}"
do
codeigottadowith $i
done
exit
It doesn't work, and I found that even when I try to just declare a simple array with:
declare -a adobearray=(item1 item2 item3); echo $adobearray[1];
The output is item1[1]. It takes the first element and makes that the whole array. Why is this wrong? What dumb thing am I doing? And is there a better way in bash to send the output of ls to an array?
Thanks for your help!
Upvotes: 1
Views: 917
Reputation: 296039
#!/bin/bash
# Cause a glob with no results to result in empty output, rather than to evaluate
# back to itself.
shopt -s nullglob
# Expand the glob /Applications/*Adobe* into an array
adobe_array=( /Applications/*Adobe* )
# Trim the prefix /Applications/ from each element of that array
adobe_array=( "${adobe_array[@]#/Applications/}" )
# Iterate over that array
for i in "${adobe_array[@]}"; do
codeigottadowith "$i"
done
ls
is inherently fault-prone. The command is designed for its output to be read by humans, not programs, and it doesn't support functionality (such as NUL-delimited output) necessary to resolve the related issues robustly.adobearray=( 'cat "adobeapps" ')
-- this puts the string cat "adobeapps"
itself into the array as its only element; it doesn't actually run the cat
command at all. If you did want to read from a file into an array, you'd be better off using mapfile
instead (if targeting bash 4.0 or newer), though reading from a file generated with ls
is inappropriate in the first place.adobearray=( $(cat "adobeapps") )
-- This is closer, but also buggy. If an application name contains a space (and Adobe Acrobat
and Adobe Photoshop
all contain spaces), you would have Adobe
as one entry and Acrobat
as another. And if you had a program named * Adobe Foobar *
, then the *
s would be replaced with names of other files in the current directory where this code was invoked.echo $adobearray[1]
-- in order to index into an array, one needs to use braces to surround the parameter expansion; use echo "${adobearray[1]}"
to emit the second item in your array (the first is index 0).Upvotes: 6