1

I am trying to store the output of this:

mdfind "kMDItemContentType == 'com.apple.application-bundle'" 

Output is like this:

/Applications/Safari.app
/Applications/Xcode.app
/Applications/Xcode.app/Contents/Applications/Accessibility Inspector.app
/Applications/Xcode.app/Contents/Applications/RealityComposer.app
/Applications/Xcode.app/Contents/Applications/FileMerge.app
/Applications/Xcode.app/Contents/Applications/Instruments.app
/Applications/Xcode.app/Contents/Applications/Create ML.app

I try to store it as an array but the contents are split per spaces:

bash-5.1$ arr=( $(/usr/bin/mdfind "kMDItemContentType == 'com.apple.application-bundle'") )
bash-5.1$ echo ${arr[2]}
/Applications/Xcode.app/Contents/Applications/Accessibility
bash-5.1$ echo ${arr[3]}
Inspector.app
bash-5.1$ 

So how can I do the trick?

2
  • 4
    Use readarray aka mapfile (see the manual) Commented Mar 11, 2022 at 14:19
  • 1
    Also, use the -0 option to use a null byte, rather than a newline, to mark the end of a path. Commented Mar 11, 2022 at 14:21

1 Answer 1

2

Use readarray and process substitution to read a null-delimited series of paths into an array.

readarray -d '' arr < <(mdfind -0 "...")

The -0 option tells mdfind to terminate each path with a null byte instead of a linefeed. (This guards agains rare, but legal, path names that include linefeeds. Null bytes are not a valid character for any path component.)

The -d '' option tells readarray to treat the null byte as the end of a "line".

readarray populates an array with one "line" of input per element. The input is the output of mdfind; the process substitution ensures that readarray executes in the current shell, not a subshell induced by a pipe like

mdfind -0 "..." | readarray -d '' arr

(Under some situations, you can make the last job of a pipeline execute in the current shell; that's beyond the scope of this answer, though.)


Example:

# Using printf to simulate mdfind -0
$ readarray -d '' arr < <(printf 'foo\nbar\000baz\000')
$ declare -p arr
declare -a arr=([0]=$'foo\nbar' [1]="baz")
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.