[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Fastest way to join an array into a string
From: |
Stephane Chazelas |
Subject: |
Re: [Help-bash] Fastest way to join an array into a string |
Date: |
Tue, 27 Aug 2019 06:47:47 +0100 |
User-agent: |
NeoMutt/20171215 |
2019-08-26 13:47:36 -0500, Peng Yu:
[...]
> echo -n "$1"
You can't use echo for arbitrary data. Depending on the
environment and how bash was built, that will either
- output that -n
- fail if $1 is -n, -E, -e or any combination like -neEneE
- fail if $1 contains backslashes
Use printf again: printf %s "$1"
> shift
You'll get an error if $@ is the empty list (no argument).
> if (($#)); then
> declare x
Why "declare x"
> printf "${separator//%/%%}%s" "$@"
[...]
You also need to escape \. You're also missing the newline
delimiter.
Note that if you're printing it, that means that if you need to
store it in a variable, you'll need to use command substitution,
which involves running an extra process and writing/reading the
data through a pipe.
Even if you use printf -v, like in:
join_into() {
local -n _var="$1"
local _sep="$2"
shift 2
if (($# > 1)); then
sep=${sep//%/%}
sep=${sep//\\/\\\\}
printf -v _var "${separator//%/%%}%s" "${@:2}"
_var=$1$_var
else
_var=$1
fi
}
I find it's still orders of magnitude slower than the approach that uses
${*/#/$sep}.
On my system, it is significantly slower than invoking perl or python
like
result=$(perl -le 'print join shift, @ARGV' -- sep "$@")
or
result=$(python -c 'import sys; print(sys.argv[1].join(sys.argv[2:]))' sep "$@")
--
Stephane