如何在Bash中将字符串转换为单个字符数组?

时间:2017-04-12 05:26:42

标签: bash

我如何拍摄一个简单的字符串,例如" Hello World!"并将其拆分为各自的角色?

使用上面的例子,我想要一个在每个值中放入一个字符的数组。因此阵列的内部结构看起来像是:

{{1}}

8 个答案:

答案 0 :(得分:3)

str="Hello world!"
for (( i=0 ; i < ${#str} ; i++ )) {
    arr[$i]=${str:i:1}
}

#print
printf "=%s=\n" "${arr[@]}"

输出

=H=
=e=
=l=
=l=
=o=
= =
=w=
=o=
=r=
=l=
=d=
=!=

您可以使用

将任何命令的结果分配到数组中
mapfile -t array < <(command args)

不幸的是,定义自定义分隔符-d需要bash 4.4。+。比方说,想要将上面的字符串分成2个字符 - 使用grep

mapfile -t -d ''  a2 < <(grep -zo .. <<<"$str")
printf "=%s=\n" "${a2[@]}"

输出:

=He=
=ll=
=o =
=wo=
=rl=
=d!=

答案 1 :(得分:1)

Pure Bash方法 - 一次遍历字符串一个字符并抓取子字符串:

#!/bin/bash

declare -a arr
string="Hello World!"
for ((i = 0; i < ${#string}; i++)); do
   # append i'th character to the array as a new element
   # double quotes around the substring make sure whitespace characters are protected 
  arr+=("${string:i:1}")
done

declare -p arr
# output: declare -a arr=([0]="xy" [1]="y" [2]="H" [3]="e" [4]="l" [5]="l" [6]="o" [7]="W" [8]="o" [9]="r" [10]="l" [11]="d" [12]="!")

答案 2 :(得分:1)

我可以看到两种方法。在纯Bash中,逐个字符地迭代字符串并将每个字符添加到数组中:

$ str='Hello World!'
# for (( i = 0; i < ${#str}; ++i )); do myarr+=("${str:i:1}"); done
$ declare -p myarr
declare -a myarr='([0]="H" [1]="e" [2]="l" [3]="l" [4]="o" [5]=" " [6]="W" [7]="o" [8]="r" [9]="l" [10]="d" [11]="!")'

关键元素是子字符串扩展"${str:i:1}",它扩展为str的子字符串,从索引i开始,长度为1.请注意,这是少数几个之一您不必使用$添加变量来获取其内容的时间,因为此处i位于算术上下文中。

使用外部工具fold

$ readarray -t arr <<< "$(fold -w 1 <<< "$str")"
$ declare -p arr
declare -a arr='([0]="H" [1]="e" [2]="l" [3]="l" [4]="o" [5]=" " [6]="W" [7]="o" [8]="r" [9]="l" [10]="d" [11]="!")'

fold -w 1将输入字符串换行为每行一个字符,readarray命令逐行读取其输入到数组中(-t从每个元素中删除换行符)

请注意readarray需要Bash 4.0或更新版本。

答案 3 :(得分:1)

使用数组索引在bash中进行相当简单的操作。只需循环遍历所有字符然后选择关闭到数组中,例如

#!/bin/bash

a="Hello World!"

for ((i = 0; i < ${#a}; i++)); do 
    array+=("${a:i:1}")           ## use array indexing for individual chars
done

printf "%s\n" "${array[@]}"       ## output individual chars

示例使用/输出

$ sh bashchar.sh
H
e
l
l
o

W
o
r
l
d
!

答案 4 :(得分:0)

试试这个 -

$v="Hello World!"
$awk  '{n=split($0,a,""); for(i=1;i<=n;i++) {print a[i]}}' <<<"$v"
H
e
l
l
o

W
o
r
l
d
!

答案 5 :(得分:0)

awk '{ for ( i=1;i<=length($0);i++ ) printf substr($0,i,1)"\n" }' <<< $str
mapfile arry1 < <(echo "$str1")

答案 6 :(得分:0)

如果您尝试生成JSON,请使用square而不是大括号和jq而不是Bash:

command =  "ssh abc@xyz \"awk 'FNR==2{$2=1};1' file_from > file_to\""
commands.getoutput(command)

答案 7 :(得分:0)

为了多样化,纯Bash的解决方案没有数组索引:

string="Hello world"
split=( )
while read -N 1; do
    split+=( "$REPLY" )
done < <( printf '%s' "$string" )

最后一行确实处理替换以将printf的输出传递给循环。循环使用read -N 1一次只读取一个字符。