Matter
Matter

Reputation: 449

Bash loop command through list containing spaces

I have a script with multiple loop commands using the same list. It looks like this:

# List of applications
read -r -d '' Applications << EndOfList
/Applications/App.app
/Applications/App2.app
/Applications/App3.app
/Applications/Another App.app
EndOfList

for file in $Applications
do
    if [ -e "$file" ]; then
        echo ""$file" found"
    fi;
done

exit 1

This seems to work fine except for the fourth application in the list, because there's a space in the application name. If I run the script in debug mode, this is the output:

+ read -r -d '' Applications
+ for file in '$Applications'
+ '[' -e /Applications/App.app ']'
+ for file in '$Applications'
+ '[' -e /Applications/App2.app ']'
+ for file in '$Applications'
+ '[' -e /Applications/App3.app ']'
+ for file in '$Applications'
+ '[' -e /Applications/Another ']'
+ for file in '$Applications'
+ '[' -e App.app ']'
+ exit 1

I've tried escaping with a backslash, quoting it and multiple other ways but I could not get it to work.

Upvotes: 1

Views: 1528

Answers (2)

anubhava
anubhava

Reputation: 785206

You should set IFS as \n while reading and use BASH array rather a simple variable to hold all the entries delimited by newlines:

#!/bin/bash 

IFS=$'\n' read -r -d '' -a Applications <<'EndOfList'
/Applications/App.app
/Applications/App2.app
/Applications/App3.app
/Applications/Another App.app
EndOfList

for file in "${Applications[@]}"
do
    if [[ -e "$file" ]]; then
        echo "$file found"
    fi;
done

PS: If you have BASH 4+ version then use mapfile:

mapfile -t Applications <<'EndOfList'
/Applications/App.app
/Applications/App2.app
/Applications/App3.app
/Applications/Another App.app
EndOfList

Upvotes: 2

ClaudioM
ClaudioM

Reputation: 1446

why you should use a list instead to get apps file name directly from directory? If you should add new app in the future, you must update the script.

maybe this could be an idea to get file from dir: I've created a directory Applications, and touched the 4th files in your script:

#!/bin/bash

# List of applications


for file in Applications/*.app
do
        echo "file[$file]"
    if [ -e "$file" ]; then
        echo ""$file" found"
    fi;
done

exit 1

output

[shell] ➤ ./tttttt
file[Applications/Another App.app]
Applications/Another App.app found
file[Applications/App.app]
Applications/App.app found
file[Applications/App2.app]
Applications/App2.app found
file[Applications/App3.app]
Applications/App3.app found

Upvotes: 0

Related Questions