10

Given a command that outputs multiple strings separated by null bytes, what's the best (fastest) way to convert this into an array in bash.

eg:

git ls-files -z
5
  • That is the right approach Commented Jan 10, 2019 at 11:33
  • 2
    Is IFS= really necessary? help readarray (or rather help mapfile) suggests that IFS is not used since mapfile doesn't use wordsplitting like read, but always splits on newlines or the symbols given by -d. Commented Jan 10, 2019 at 12:04
  • Question had answer included, was: This works but seems a bit clunky: IFS= readarray -t -d '' MY_ARRAY < <(git ls-files -z) Could include this as an answer instead. Commented Jan 10, 2019 at 21:10
  • @Socowi, you're right, IFS isn't needed. Thanks Commented Jan 10, 2019 at 21:11
  • 1
    ...mind you, I don't generally advise judging quality of bash code on "clunkiness", if you consider clunkiness and verbosity to be one and the same; the historical legacy of compatibility with decades of shells (and, occasionally, formalized standards) with conflicting, oft-poorly-considered semantics means that a substantial amount of defensive programming is often called for if one wants robust, predictable behavior. Consequently, longer code can often be easier for fellow developers to reason about, if that verbosity is used to foreclose potential corner cases. Commented Jan 11, 2019 at 3:27

1 Answer 1

7

For bash 4.4 and later:

mapfile -d '' arrayVar < <(git ls-files -z)
# note the space    here^

Docs for mapfile


For bash 4.3 and earlier:

arrayVar=( )
while IFS= read -r -d '' item; do
  arrayVar+=( "$item" )
done < <(git ls-files -z)
#note ^here is a space

Note that you cannot use pipes regardless of bash version, ex:

# !! Example of incorrect code:
git ls-files -z | mapfile -d '' arrayVar

will not work (unless lastpipe is enabled and active, see shopt), because pipes implicitly create a subshell. See BashFAQ#024.

Sign up to request clarification or add additional context in comments.

3 Comments

Why IFS=? Won't IFS be ignored if there is only one variable to read into?
@WillPalmer, not quite ignored -- you still get leading and trailing whitespace stripped.
@Shelvacu, ...edited a little further -- probably appropriate to mention lastpipe when making a declarative "will not work" statement.

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.