使用shell脚本将输出分成多个变量

时间:2019-04-27 00:26:34

标签: bash shell

所以我有一个输出许多数字的C程序。我必须全部检查一下。问题是,每次我运行程序时,都需要更换种子。为此,我一直在手动进行操作,并尝试制作一个shell脚本来解决此问题。

我尝试使用sed,但无法做到这一点。

我正在尝试获得如下输出:

a=$(./algorithm < input.txt)
b=$(./algorithm2 < input.txt)
c=$(./algorithm3 < input.txt)

每个算法程序的输出如下:

12 13 315
1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5

因此变量a具有所有这些输出,而我需要的是

变量a包含整个字符串 而变量a1仅包含第三个数字,在这种情况下为315。

另一个例子:

2 3 712
1 23 15 12 31 23 3 2 5 6 6 1 2 3 5 51 2 3 21 

echo $b应该提供以下输出:

2 3 712
1 23 15 12 31 23 3 2 5 6 6 1 2 3 5 51 2 3 21 

echo $b1应该给出以下输出:

712

谢谢!

3 个答案:

答案 0 :(得分:3)

并非完全是您要的内容,但是一种实现方法是将算法的结果存储在数组中,然后取消对感兴趣的项的引用。你会写类似的东西:

a=( $(./algorithm < input.txt) )  
b=( $(./algorithm2 < input.txt) )
c=( $(./algorithm3 < input.txt) )

请注意将语句括起来的多余的()。现在,abc是数组,您可以访问感兴趣的项目,例如${a[0]}$a[1]

对于您的特定情况,由于您需要第三个元素,因此该元素应为index = 2,因此:

a1=${a[2]}
b1=${b[2]}
c1=${c[2]}

答案 1 :(得分:2)

由于使用的是Bash shell(请参见标签),因此可以使用Bash数组轻松访问输出字符串中的各个字段。例如这样的

#!/bin/bash

# Your lines to gather the output:
# a=$(./algorithm < input.txt)
# b=$(./algorithm2 < input.txt)
# c=$(./algorithm3 < input.txt)

# Just to use your example output strings:
a="$(printf "12 13 315 \n 1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5")"
b="$(printf "2 3 712 \n 1 23 15 12 31 23 3 2 5 6 6 1 2 3 5 51 2 3 21")"

# Put the output in arrays.
a_array=($a)
b_array=($b)

# You can access the array elements individually.
# The array index starts from 0.
# (The names a1 and b1 for the third elements were your choice.)
a1="${a_array[2]}"
b1="${b_array[2]}"

# Print output strings.
# (The newlines in $a and $b are gobbled by echo, since they are not quoted.)
echo "Output a:" $a
echo "Output b:" $b

# Print third elements.
echo "3rd from a: $a1"
echo "3rd from b: $b1"

此脚本输出

Output a: 12 13 315 1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5
Output b: 2 3 712 1 23 15 12 31 23 3 2 5 6 6 1 2 3 5 51 2 3 21
3rd from a: 315
3rd from b: 712

说明:

这里的窍门是Bash中的数组常量(文字)具有以下形式

(<space_separated_list_of_elements>)

例如

(1 2 3 4 a b c nearly_any_string 99)

任何分配了此类数组的变量都会自动成为数组变量。在上面的脚本中,这是在a_array=($a)中发生的事情:Bash将$a扩展为<space_separated_list_of_elements>,并再次读取整个表达式并将其解释为数组常量。

通过使用以下形式的表达式,可以像引用变量一样引用此类数组中的单个元素

<array_name>[<idx>]

就像一个变量名。其中,<array_name>是数组的名称,<idx>是引用单个元素的整数。对于由数组常量表示的数组,索引从零开始连续计数元素。因此,在脚本中,${a_array[2]}扩展为数组a_array中的第三个元素。如果数组中的元素较少,则a_array[2]将被视为未设置。

您可以分别通过以下方式输出数组a_array中的所有元素,相应的索引数组以及数组中的元素数

echo "${a_array[@]}"
echo "${!a_array[@]}"
echo "${#a_array[@]}"

这些命令可用于追踪换行符的命运:鉴于上面的脚本,它仍然位于$a中,如(观察引号)所示。

echo "$a"

产生

12 13 315
 1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5

但是换行符未将其放入数组a_array中。这是因为Bash认为它是分隔数组分配中第三个和第四个元素的空白的一部分。如果换行符之间没有多余的空格,则同样适用,例如:

12 13 315\n1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5

我实际上假设您的C程序的输出以这种形式出现。

答案 2 :(得分:1)

这会将完整字符串存储在a[0]中,并将各个字段存储在a[1-N]中:

$ tmp=$(printf '12 13 315\n1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5\n')

$ a=( $(printf '_ %s\n' "$tmp") )

$ a[0]="$tmp"

$ echo "${a[0]}"
12 13 315
1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5

$ echo "${a[3]}"
315

显然,在您的真实代码中将$(printf '12 13 315\n1 2 3 4 5 6 7 8 10 2 8 9 1 0 0 2 3 4 5\n')替换为$(./algorithm < input.txt)