打印在Bash中存储命令输出的字符串变量。
打印在Bash中存储命令输出的字符串变量。
我需要将Bash命令的输出放入一个字符串变量中。每个值应该用一个空格分隔。有很多方法可以做到这一点,但是我不能使用mapfile
或read
选项(我在macOS上使用的是Bash < 4版本)。
这是命令的输出:
values="$(mycommand | awk 'NR > 2 { printf "%s\n", $2 }')"
其中mycommand
只是一个获取一些值的云命令,类似于:
echo $values
mycommand的输出:(我认为每个值都以\n结尾的字符串)
55369972 75369973 85369974 95369975
这是我想要做的:
在这里,我应该像这样打印这些值(我需要迭代变量values
,以便可以逐个打印每个值)。
循环中期望的输出
value: 55369972 value: 75369973 value: 85369974 value: 95369975
但我得到的结果是这样的:
value: 55369972 75369973 85369974 95369975
# 获取values的id字段 values="$(mycommand| awk 'NR > 2 { printf "%s\n", $2 }')" # 将换行符替换为空格,以便可以迭代每个值 new_values="${values//$'\n'/ }" # new_values=("${values//$'\n'/ }") # 检查是否可以正确打印每个值 for i in "${new_values[@]}" # for i in "$new_values" do echo "value: ${i}" done
另外,我不能使用类似于
# shellcheck disable=xxx values=($(echo "${values}" | tr "\n" " "))
因为当检查代码时我收到错误信息...
有没有人知道我在代码中做错了什么?
问题的原因是在使用Bash中的命令输出作为字符串变量时,如果想要将该字符串拆分为列表,需要使用方括号将其括起来。解决方法是使用替换操作符将换行符替换为空格,并将结果存储在一个新的数组变量中。
以下是解决该问题的代码示例:
# 获取命令输出中的id字段的值 values="$(mycommand| awk 'NR > 2 { printf "%s\n", $2 }')" # 将换行符替换为空格 new_values=("${values//$'\n'/ }") # 检查是否可以正确打印出数值 for i in ${new_values} do echo "value: ${i}" done
其中关键的部分是 `new_values=("${values//$'\n'/ }")`,在遍历时不要将其放在引号中(或者将其转换回字符串)。
如果在替换了换行符为一个空格并将值放入列表之后,仍然无法正确输出 `value: value01 value02 value03...`,可能是因为命令的输出字符串末尾有一个换行符(如果我理解错了,请纠正我)。在 `for loop` 中获得的输出是 `value_value01 value02 value03 ...`。
你可以尝试使用以下代码进行测试:`values="1 2 3 5"`,作为你输入的替代内容,看看是否能够正常工作。请确认你的 `for loop` 是否为 `for i in ${new_values}`,没有任何引号包裹。
抱歉,即使是`values=$'1\n2\n3\n5'`也是可以的(Markdown不允许我在评论中写换行符)。
问题的原因是输出的字符串变量的每个值都以换行符结尾,导致代码中的循环无法正确执行。解决方法是使用重定向操作符">"将命令的输出重定向到一个文件中,并使用类似于"od"的工具查看每行结尾使用的字符。
以下是解决问题的完整代码示例:
#!/bin/bash # Getting the id field of the values values=$(your_command > output.txt) # 将命令的输出重定向到文件output.txt中 # for v in $values; do echo value: "$v" done
然后,使用以下命令使用"od"工具查看output.txt文件中每行的结尾字符:
od -c output.txt
以上方法可以帮助您检查每个值的结尾字符,并根据需要进行进一步的处理。
问题出现的原因是输出的字符串中每个字段的末尾都有'\n',导致无法正确地将输出存储到变量中。尝试过添加IFS=' '或修改awk命令的输出格式,但都没有解决问题。可能是由于使用的是macOS中的zhs shell,而不是bash shell导致的问题。
解决方法是修改从云端获取数据的方式。例如,可以使用以下命令:
IFS=$'\n' regions=($(az account list-locations --query "[].name" -o tsv)) for region in "${regions[@]}"; do echo "$region" done
这样可以正确地将输出存储到变量中,并使用for循环逐个打印每个值。