我有一根绳子-w o rd
。
我需要将其拆分为w o r d
数组或数组,因为'w' 'o' 'r' 'd'
这并不重要。
我尝试过以下方法
IFS='\0- ' read -a string <<< "-w o rd"
echo ${string[*]}
rd
没有被分裂。我怎样才能让它分开
答案1
你不能在 bash 中使用 IFS 来分割任何东西(它有成为一个角色)。r
和d
之间没有字符rd
。没有空格和没有字符与空字符不同。
如果您希望每个字符作为数组中的单独元素,我能想到的一种方法是单独读取每个字符并将其附加到数组中(并使用 IFS 去除空格和-
):
bash-4.4$ while IFS=' -' read -n1 c ; do [[ -n $c ]] && foo+=("$c"); done <<<"-w o rd"
bash-4.4$ declare -p foo
declare -a foo=([0]="w" [1]="o" [2]="r" [3]="d")
答案2
您可以使用以下方法删除不需要的字符${var//pattern/replacement}
:
s='-w o rd'
s=${s//[- ]}
然后使用子字符串扩展一次选择一个字符:
$ for ((i=0; i < ${#s}; i++)); do
echo ${s:i:1}; # or do whatever you like here
done
(它甚至似乎可以处理多字节字符,至少在我的系统上是这样。)
请注意,IFS='\0- '
将分配一个文字反斜杠,IFS
因为反斜杠在单引号内没有特殊含义。八进制转义可以在 中工作$'...'
,但 Bash 中的变量不能包含 NUL 字节,所以这没有帮助。 (字符串在 NUL 上被剪切,因此例如x=$'foo\0bar'; printf "%q\n" "$x"
仅打印foo
。另外,@muru 所说的,在 NUL 字节上拆分与在每个字符之间拆分不同)
答案3
如果你的字符串不太长:
w='-w o rd baa'
w=${w//[!a-z]} # strip anything but lower case letters
eval echo '${w:'{0..10}':1}'
eval array=\( '${w:'{0..10}':1}' \)
echo "${array[@]}"
w o r d b a a
您可以将愚蠢的事情变成更糟糕的事情,IFS 和 glob 安全,并且考虑到大括号的相对顺序以及 ,zsh
和bash
之间的变量扩展ksh
:
args(){ printf '<%s> ' "$@"; echo; }
w='-e a * () \n peek
fo*"x'"'q"
eval eval args "'\"\${w:'{0..$((${#w}-1))}':1}\"'"
eval eval 'array=\(' "'\"\${w:'{0..$((${#w}-1))}':1}\"'" '\)'
args "${array[@]}"
<-> <e> < > <a> < > <*> < > <(> <)> < > <\> <n> < > <p> <e> <e> <k> <
> < > <f> <o> <*> <"> <x> <'> <q>
但坦率地说,这种怪物的唯一用途可能是吓跑新手,并通过假设对 shell 语言细节的深入了解来给傻瓜留下深刻印象;-)