如何在bash中迭代多行变量?

时间:2017-07-06 22:15:54

标签: bash

鉴于

# this is programmatically generated... hard-coded here for this example
commands="\nthing1@this is thing 1!\nthing2@this is thing 2!"

while read -r line; do
  cmd=$(printf "$line" | cut -d'@' -f1 | tr -d '\n')
  desc=$(printf "$line" | cut -d'@' -f2 | tr -d '\n')

  printf '  %-20s %s\n' "$cmd" "$desc"
done <<< "$commands"

我希望输出

  thing1        this is thing1!
  thing2        this is thing2!

相反,我得到

  thing1thing2        this is thing1!this is thing2!

我做错了什么?

我希望read超过换行符,因此我可以cut@相应地printf

2 个答案:

答案 0 :(得分:0)

#!/bin/bash

input="\nthing1@this is thing 1!\nthing2@this is thing 2!"

# echo replaces '\n's with real new-lines
# readarray -t loads the multiline string into an array
readarray -t array <<< $(echo -e "${input}")

# loop it
for command in "${array[@]}"; do
    echo "${command}"
done

答案 1 :(得分:0)

根据你的问题,当与这里的字符串一起使用时,bash似乎没有解释任何\n \t \f e.t.c。这可能是你想要的,也可能是不好的做法。并且双引号周围的感叹号将导致错误,因为bash将尝试将其评估为事件(在某些时候在shell上执行的命令),因此您必须转义它(当从终端使用时)

commands="\nthing1@this is thing 1\!\nthing2@this is thing 2!"

while read line;do
   // do your stuff here
line <<< $( echo -e "${commands}" )  # -e switch tells the echo command to honour all back slashes . The same behaviour can be achieved with `shopt -s xpg_echo` ( you have to remove -e switch whenever you do that )

noise: 注意:从终端使用时:如果仔细查看命令变量,我没有反斜杠&#34;!&#34;这是因为它没有任何值,因此bash不会尝试将前面的值定位为事件。

如果您愿意,请查看bash手册页的历史记录扩展部分以获取更多相关信息