在bash中将多行输出捕获为数组

dje*_*lin 58 bash

如果inner.sh是的话

#...
echo first
echo second
echo third
Run Code Online (Sandbox Code Playgroud)

而且outer.sh

var=`./inner.sh`
# only wants to use "first"...  
Run Code Online (Sandbox Code Playgroud)

如何var通过空格分割?

sam*_*hen 80

试试这个:

var=($(./inner.sh))

# And then test the array with:

echo ${var[0]}
echo ${var[1]}
echo ${var[2]}
Run Code Online (Sandbox Code Playgroud)

输出:

first
second
third
Run Code Online (Sandbox Code Playgroud)

说明:

  • 例如,您可以通过执行bash来创建数组var=(first second third).
  • $(./inner.sh)运行该inner.sh脚本,它打印出来first,secondthird在不同的行.由于我们没有将双引号括起来$(...),所以它们被集中在同一条线上,但是用空格分隔,所以你最终会看到它在前一个项目符号中的样子.

  • 这个答案实际上将**单词**而不是**行**分成数组元素.从技术上讲,它回答了问题,但不是更一般的情况.测试用例:`var =($(echo"1 2 3"; echo"4 5 6")); echo $ {var [0]}`我期望"1 2 3",它产生"1".取决于您的用例.`mapfile`做我需要的. (14认同)
  • 正如@StéphaneGourichon指出的那样,这会分裂单词而不是行,所以这不适用于空行,它们被简单地忽略,这有效地搞砸了数组中行的顺序 (4认同)
  • 看看最后的答案,这种方法是很好的问题,但如果你需要更多的东西(像保持在机智分隔,每行后自动调用一个函数读取等),然后映射文件目前是更强大的+这是超级高效,我已经用很多程序对它进行了测试,我甚至不需要等待很长时间才能获得100,000行的文件.通常情况下,假设您使用的是本地存储:) (3认同)

gni*_*urf 37

不要忘记内置mapfile.在你的情况下,它绝对是最有效的:如果你想在一个数组中啜饮整个文件,其中的字段将是输出的行./inner.sh,

mapfile -t array < <(./inner.sh)
Run Code Online (Sandbox Code Playgroud)

然后你会有第一行${array[0]},等等......

有关此内置和所有可能选项的更多信息:

help mapfile
Run Code Online (Sandbox Code Playgroud)

如果你只需要调用变量中的第一行firstline,请执行

read -r firstline < <(./inner.sh)
Run Code Online (Sandbox Code Playgroud)

这些绝对是最有效的方式!

这个小基准将证明:

$ time mapfile -t array < <(for i in {0..100000}; do echo "fdjsakfjds$i"; done)

real    0m1.514s
user    0m1.492s
sys 0m0.560s
$ time array=( $(for i in {0..100000}; do echo "fdjsakfjds$i"; done) )

real    0m2.045s
user    0m1.844s
sys 0m0.308s
Run Code Online (Sandbox Code Playgroud)

如果您只想要输出第一行的第一个单词(带空格分隔符)./inner.sh,则最有效的方法是

read firstword _ < <(./inner.sh)
Run Code Online (Sandbox Code Playgroud)

  • ***WTF***是mapfile?_` brew info mapfile || echo"发现$(brew desc -s mapfile | wc -l)引用mapfile"` - >**`错误:mapfile没有可用的公式``找到0引用mapfile`**让我继续...... sh-3.2 $ mapfile` - >**`sh:mapfile:command not found`** (4认同)
  • @alexgray`ma​​pfile`是Bash≥4内置.不适用于POSIX shell或Bash <4.好像你正在运行3.2; 你完蛋了.除非您安装了更新版本的Bash. (3认同)
  • 这个答案确实将**行**分成了一个数组.测试用例:`mapfile -t var <<(echo"1 2 3"; echo"4 5 6"); echo $ {var [1]}`正确地产生`4 5 6`. (3认同)
  • imo:这里最好的答案,mapfile到目前为止比其他方法更快,我正在使用输出行> 14,000个条目,mapfile几乎是瞬间工作而不是使用外部程序,我使用经验法则从不涉及其他程序完成语言应该为自己做的工作,而bash也不例外,当使用变量时,该规则会变为两倍. (2认同)

Arn*_*tig 6

你不是在空白上分裂,而是在新行上分裂.给这个旋转:

IFS=$'
'

var=$(./echo.sh)
echo $var | awk '{ print $1 }'
unset IFS
Run Code Online (Sandbox Code Playgroud)