将Bash数组转换为分隔的字符串

[英]Converting a Bash array into a delimited string


I would like to know the following;

我想知道以下内容;

  1. Why the given non-working example doesn't work.
  2. 为什么给定的非工作示例不起作用。
  3. If there are any other cleaner methods than those given in working example.
  4. 如果有任何其他清洁方法,而不是工作示例中给出的方法。

Non-working example

非工作的例子

> ids=(1 2 3 4);echo ${ids[*]// /|}
1 2 3 4
> ids=(1 2 3 4);echo ${${ids[*]}// /|}
-bash: ${${ids[*]}// /|}: bad substitution
> ids=(1 2 3 4);echo ${"${ids[*]}"// /|}
-bash: ${"${ids[*]}"// /|}: bad substitution

Working example

工作实例

> ids=(1 2 3 4);id="${ids[@]}";echo ${id// /|}
1|2|3|4
> ids=(1 2 3 4); lst=$( IFS='|'; echo "${ids[*]}" ); echo $lst
1|2|3|4

In context, the delimited string to be used in a sed command for further parsing.

在上下文中,用于sed命令的分隔字符串用于进一步解析。

3 个解决方案

#1


23  

# REVISION: 2017-03-14
# Use of read and other bash specific features (bashisms)

Because parentheses are used to delimit an array, not a string:

因为括号用于分隔数组,而不是字符串:

ids="1 2 3 4";echo ${ids// /|}
1|2|3|4

Some samples: Populating $ids with two strings: a b and c d

一些示例:用两个字符串填充$ id:a b和c d

ids=("a b" "c d")

echo ${ids[*]// /|}
a|b c|d

IFS='|';echo "${ids[*]}";IFS=$' \t\n'
a b|c d

... and finally:

......最后:

IFS='|';echo "${ids[*]// /|}";IFS=$' \t\n'
a|b|c|d

Where array is assembled, separated by 1st char of $IFS, but with space replaced by | in each element of array.

组装数组时,由$ IFS的第一个字符分隔,但空格替换为|在数组的每个元素中。

When you do:

当你这样做时:

id="${ids[@]}"

you transfer the string build from the merging of the array ids by a space to a new variable of type string.

您将字符串构建从数组ID的空间合并传输到字符串类型的新变量。

Note: when "${ids[@]}" give a space-separated string, "${ids[*]}" (with a star * instead of the at sign @) will render a string separated by the first character of $IFS.

注意:当“$ {ids [@]}”给出一个以空格分隔的字符串时,“$ {ids [*]}”(带有星号*而不是at符号@)将呈现由第一个字符分隔的字符串$ IFS。

what man bash says:

什么人打击说:

man -Len -Pcol\ -b bash | sed -ne '/^ *IFS /{N;N;p;q}'
   IFS    The  Internal  Field  Separator  that  is used for word splitting
          after expansion and to split  lines  into  words  with  the  read
          builtin command.  The default value is ``<space><tab><newline>''.

Playing with $IFS:

玩$ IFS:

set | grep ^IFS=
IFS=$' \t\n'

declare -p IFS
declare -- IFS=" 
"
printf "%q\n" "$IFS"
$' \t\n'

Literally a space, a tabulation and (meaning or) a line-feed. So, while the first character is a space. the use of * will do the same as @.

字面意思是空格,制表和(意义或)换行。所以,虽然第一个角色是一个空间。使用*将与@相同。

But:

但:

{

    # OIFS="$IFS"
    # IFS=$': \t\n'
    # unset array 
    # declare -a array=($(echo root:x:0:0:root:/root:/bin/bash))

    IFS=: read -a array < <(echo root:x:0:0:root:/root:/bin/bash)

    echo 1 "${array[@]}"
    echo 2 "${array[*]}"
    OIFS="$IFS" IFS=:
    echo 3 "${array[@]}"
    echo 4 "${array[*]}"
    IFS="$OIFS"
}
1 root x 0 0 root /root /bin/bash
2 root x 0 0 root /root /bin/bash
3 root x 0 0 root /root /bin/bash
4 root:x:0:0:root:/root:/bin/bash

Note: The line IFS=: read -a array < <(...) will use : as separator, without setting $IFS permanently. This is because output line #2 present spaces as separators.

注意:行IFS =:read -a array <<(...)将使用:作为分隔符,不会永久设置$ IFS。这是因为输出线#2将空格作为分隔符。

#2


12  

Your first question is already addressed in F. Hauri's answer. Here's canonical way to join the elements of an array:

你的第一个问题已在F. Hauri的答案中得到解决。这是加入数组元素的规范方法:

ids=( 1 2 3 4 )
IFS=\| eval 'lst="${ids[*]}"'

Some people will cry out loud that eval is evil, yet it's perfectly safe here, thanks to the single quotes. This only has advantages: there are no subshells, IFS is not globally modified, it will not trim trailing newlines, and it's very simple.

有些人会大声喊叫说eval是邪恶的,但是由于单引号,它在这里非常安全。这只有一个优点:没有子shell,IFS没有全局修改,它不会修剪尾随换行符,而且非常简单。

#3


3  

You can use printf too, without any external commands or the need to manipulate IFS:

您也可以使用printf,无需任何外部命令或需要操作IFS:

ids=(1 2 3 4)                     # create array
printf -v ids_d '|%s' "${ids[@]}" # yields "|1|2|3|4"
ids_d=${ids_d:1}                  # remove the leading '|'
智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2012/11/20/6a242abb707f7bf04c540622e9bb9872.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告