使用Shell脚本将输出分割为多个变量

4

我有一个输出许多数字的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

谢谢!


第一行缺少了一个 \n ,不好意思! - Armandus Filtch
3个回答

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]}

太棒了,我现在就去尝试一下。很快就会回来的!谢谢。 - Armandus Filtch
嘿Sal,我试了你的代码,但是输出了这个:a1命令未找到! - Armandus Filtch
哦,去掉 = 周围的空格。我会修正答案。 - sal

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"

which yields

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将其视为分隔第三个和第四个元素的空格的一部分。如果换行符周围没有额外的空格,情况也是如此:

原始答案:Original Answer

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

我认为你的C程序输出的形式应该是这样的。"最初的回答"

所以我正在尝试这个: ``` a=($(./solveIt < entrada.txt)) a_array=($a) a1="${a_array[2]}" echo "a :$a1" ``` 但是echo输出的是"a : " - Armandus Filtch
@ArmandusFiltch:不完全正确。请尝试 a_array=($(./solveIt < entrada.txt)); a1="${a_array[2]}"; echo "a: $a1" - Jürgen
使用 .c 文件的输出是:37 19 191 \n 7 9 10 1 3 7 10 6 1 8 7 9,echo 输出是 "a : 21" D: - Armandus Filtch
只是为了确保我指向正确,"\n" 不是一个字符串,在输出中它是实际的换行符! - Armandus Filtch
@ArmandusFiltch:我更新了示例脚本。原则上,字符串中的换行符不应该破坏任何内容。请仔细检查您的Bash代码是否有额外的括号:$(./solveIt < entrada.txt)是一个字符串,而($(./solveIt < entrada.txt))是一个数组!!! - Jürgen
谢谢Jurgen做出如此出色的贡献!效果非常好 :) - Armandus Filtch

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接