javascriptmacoszshosascript

Changing Delimeter of Multiple Items Returned by a osascript/javascript File Select Dialog


I have a little zsh script I'm coding to run on MacOS. Been a bash/shell scripter for 25+ years, so it hasn't been all bad. Part of its function is to have the user select a file (or files) from a dialog using this little bit of osascript/javascript:

IMAGES="$(osascript -l JavaScript -e 'a=Application.currentApplication();a.includeStandardAdditions=true;a.chooseFile({withPrompt:"Select Image(s)",multipleSelectionsAllowed:"true"}).toString()')"

The selected files (three in this example) get dumped into the $IMAGES variable with a comma between each of them.

/Users/anderson/Pictures/1890-1899/1898/5-3-1898 John Gansemer & Lena Gansemer (nee Koltes).jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans, Mary Anderson Wedding Photo 600dpi.jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans. Mary Anderson Wedding Photo.jpg

Is there a way to get the delimiter to be something else (a pipe or something similar) that is less likely to show up in file or folder names that I am grabbing?

I've found references across the interwebs to the following the toString with a ".join" function, but I can't get the syntax right and/or might be barking up the wrong tree anyway.

Thanks,

Bill


Solution

  • In zsh, you can process strings with null bytes (unlike bash). Since NULs are not allowed in macOS filenames, it's an ideal delimiter. zsh also has a parameter expansion flag that will split a string on null bytes:

    imagesStr="$(osascript -l JavaScript -e '
      a=Application.currentApplication();
      a.includeStandardAdditions=true;
      a.chooseFile({withPrompt:"Select Image(s)",multipleSelectionsAllowed:"true"})
        .join("\0")')"
    local -a imagesAry=(${(0)imagesStr})
    

    The code above incorporates @red_menace's suggestion in the comments to call .join("\0") instead of .toString().


    The parameter expansion and command substitution can be nested:

    local -a images=(${(0)"$(osascript -l JavaScript -e '
      a=Application.currentApplication();
      a.includeStandardAdditions=true;
      a.chooseFile({withPrompt:"Select Image(s)",multipleSelectionsAllowed:"true"})
        .join("\0")')"}
    )
    print -l $#images $images
    #=> 3
    #=> /Users/me/Documents/Screen Shot 2025-08-25 at 1.42.10 PM.png
    #=> /Users/me/Documents/Screen Shot 2025-09-02 at 1.52.27 PM.png
    #=> /Users/me/Documents/Screen Shot 2025-09-02 at 1.53.41 PM.png