Julian20151006
Julian20151006

Reputation: 321

In Bash, how to split a string into array by using newline as seperator?

On Macbook Pro, I want to list every *.app in dir /Applications and save them in an array, using bash. So I wrote a bash script like this:

#!/bin/bash
cd /Applications
appstr=`ls -1 | grep .app$`
echo "appstr:"
echo "[$appstr]\n\n"

OLD_IFS=$IFS
IFS="\n"
echo "IFS=[${IFS}]"
arr=($appstr)
for app in ${arr[@]}
do
    echo App=$app
done
IFS=${OLD_IFS}

But when I run the script, the output is like this:

appstr:
[BaiduNetdisk_mac.app
Charles.app
Google Chrome.app
Lark.app
Managed Software Center.app
Microsoft Excel.app
Microsoft OneNote.app
Microsoft Outlook.app
Microsoft PowerPoint.app
Microsoft Teams.app
Microsoft Word.app
OneDrive.app
QQMusic.app
Safari.app
Scroll Reverser.app
Seal.app
Visual Studio Code.app
WeChat.app
hisuite.app
iTerm.app
sogou_mac_601a.app
zoom.us.app]


IFS=[
]
App=BaiduNetdisk_mac.app
Charles.app
Google Chrome.app
Lark.app
Ma
App=aged Software Ce
App=ter.app
Microsoft Excel.app
Microsoft O
App=eNote.app
Microsoft Outlook.app
Microsoft PowerPoi
App=t.app
Microsoft Teams.app
Microsoft Word.app
O
App=eDrive.app
QQMusic.app
Safari.app
Scroll Reverser.app
Seal.app
Visual Studio Code.app
WeChat.app
hisuite.app
iTerm.app
sogou_mac_601a.app
zoom.us.app

Apprently, arr=($appstr) treats IFS="\n" as \ and n, using n as a seperator.

So, how can I get the right answer, making $arr[0]="BaiduNetdisk_mac.app", $arr[1]="Charles.app", $arr[1]="Google Chrome.app", ..., etc. ?

Upvotes: 0

Views: 181

Answers (2)

Julian20151006
Julian20151006

Reputation: 321

Acutally, I'm asking this question for starting App from cmdline. I have got the solution, like this:

# start targetApp in /Applications, the specified targetAppName could be any sub string of the App's Name, ignoring the letter case
function start() {
    if [[ $# -eq 0 ]]
    then
        echo "usage: $FUNCNAME <targetAppName>"
        return
    fi
    local targetApp
    local APPDIR
    local pureApp
    local lowerCaseApp
    local choice
    targetApp=$(echo $1 | tr 'A-Z' 'a-z') #translate targetApp name to lower case, so when matching app's name, we can ignore the letter case
    APPDIR=/Applications
    for app in ${APPDIR}/*.app
    do
        pureApp=${app#${APPDIR}/}
        lowerCaseApp=$(echo ${pureApp} | tr 'A-Z' 'a-z')
        if [[ $lowerCaseApp =~ ${targetApp} ]]
        then
            read -p "Shall I open ${app} ? (y/Y | n/N) " -t 5 choice 
            choice=$(echo $choice | tr 'A-Z' 'a-z')
            if [[ ${choice:0:1} == "y" ]]
            then
                open "${app}"
                return
            fi
            echo
        fi
    done
    echo "${1} not found in ${APPDIR}"
}

Put the code upper into ~/.bash, and type source ~/.bashrc, then the start command works. For example:

$ start mic #try to open Microsoft Softwares
Shall I open /Applications/Microsoft Excel.app ? (y/Y | n/N)  

Shall I open /Applications/Microsoft OneNote.app ? (y/Y | n/N) 

Shall I open /Applications/Microsoft Outlook.app ? (y/Y | n/N) 

Shall I open /Applications/Microsoft PowerPoint.app ? (y/Y | n/N) y

$ start word #try to open Microsoft Word
Shall I open /Applications/Microsoft Word.app ? (y/Y | n/N) y

Upvotes: 0

choroba
choroba

Reputation: 241768

Use a glob when assigning to the array:

arr=(*.app)

Upvotes: 4

Related Questions