#!/usr/bin/env bash
k=("$(printf '\n\n\n')")
echo ${#k[@]}
k="$(printf '\n\n\n')"
echo ${#k[@]}
我发现 k 的长度都是 1,怎么样才能让它是 3 呢?
还有个类似的问题,
#!/usr/bin/env bash
f() {
local o=('' '' '')
printf '%s\n' "${o[@]}"
}
k=$(f)
echo ${#k[@]}
我想通过函数 f 来返回一个长度为 3 的空字符串数组给 k。应该怎么改才能做到呢?
1
yangg 2019-06-17 11:30:55 +08:00
k=$(printf \n\n\n)
echo ${#k[@]} |
4
Kobayashi 2019-06-18 13:41:34 +08:00
@yangg 你这种做法根本没捕捉到空字符串。你可以输出 echo ${k[@]} 试试,输出的是 nnn
@adoyle 因为你返回的是空字符串,所以需要特殊方法捕捉,直接赋值为数组是不行的。 https://gist.github.com/laggardkernel/18422f9f21063da1a7ebabb96c004e3d 另外,例 1 中,你的引号使用方法完全是错误的。建议了解一下 word-splitting,不要乱用引号。例 2 中,函数只能返回字符串。而我开头已经说过了,空字符串 "" 需要特殊照顾才能被解释到数组中的。 最后送楼主一句话:明知山有虎,…… |
5
adoyle OP @Kobayashi 感谢回复。while + read 是个好办法,如果用 bash 4 的话,可以用 readarray 来简化写法 `readarray k < <(printf '\n\n\n')`。
> 另外,例 1 中,你的引号使用方法完全是错误的。建议了解一下 word-splitting,不要乱用引号。 恩,例 1 中的引号对于我的问题的确没有意义。不过乱用引号不会造成额外问题,加引号是最保守的,除非因为引号转义符导致什么偏差,但这是别的问题了。 > In either case, quoting anyway will not break anything. So if in doubt, quote! 看了 https://mywiki.wooledge.org/WordSplitting 感觉 Word Splitting 和 IFS 真是麻烦啊.... > 最后送楼主一句话:明知山有虎,…… 诶,从接触命令行到现在一直用的是 bash,而且 bash 在大多数系统里都是默认 shell,用 bash 已经变成我的执着。 |
6
Kobayashi 2019-06-18 17:40:36 +08:00
有些地方可能让你造成了误解。
引号的问题: k=("$(printf '\n\n\n')") 中,输出结果被引起来,这样 3 个换行被当做一个字符串,数组大小必然为 1. k="$(printf '\n\n\n')" 中,问题同上,不过这次没加括号,返回的根本不是数组,就是 1 个字符串。 你在不该加引号的地方加入了引号,所以我才觉得你可能不大会用引号。先不提空字符串,这样做根本不可能捕捉到大小为 3 的数组。 最后一句话不是指 Bash,而是指捕捉空字符串这个解决方案本身就棘手,换个思路不用它才是最好的做法。 wooledge 维基我读的是 BashGuide 新手教程。单个知识点的话,可能会解释的更为详尽、繁琐,有时候没必要追究太深。 |
7
adoyle OP @Kobayashi 感谢细心指出,引号的问题如你所说,我之后也意识到这个问题,当时脑袋糊涂了,举了这个例子。
捕捉空字符串这个需求是因为我简化了问题导致看起来没意义,实际上我是为了实现一个严格的 split 函数,返回一个数组,就可能会需要返回包含多个空字符串的数组。后来我觉得函数返回数组比较难以实现,就直接去改传入参数了。 BashGuide 还没有读过,因为我之前直接读的 Bash Reference Manual。wooledge wiki 写得非常棒,能够把这些细节深挖到这地步,非常让人佩服。 |
8
james122333 2019-07-05 17:08:46 +08:00
#!/bin/bash
k=($(echo "\n" "\n" "\n")) echo ${#k[@]} for i in ${k[@]} do echo -en "$i" done > log |
9
james122333 2019-07-05 17:20:43 +08:00
感觉 newline 当空不是个好方法
不是很正规 |