【问题标题】:How to separate a variable into multiple variable in bash如何在bash中将一个变量分成多个变量
【发布时间】:2022-01-22 07:12:29
【问题描述】:
#! /bin/bash
readarray rows < Process.dat

for ((i=0, j=1; i< ${#rows[@]}; i++, j++)); do
   declare "row$j"="${rows[$i]}"

done

echo "$row1"

此代码的输出是 10110 556 4433,我尝试使用相同的代码再次更改“行”和“行”的变量但是当我这样做时没有输出,我该如何拆分变量“row1”分为 3 个单独的数字,每个数字分配给不同的变量,例如 row1_1 = 10110, row1_2 = 556, row1_3 = 4433

输入文件由 5 行 3 列数字组成:

10110 556 4433
10120 424 54
12452 123 534
22042 432 12
25321 423 73

这些列分别代表索引时间、突发时间和id号。

我需要锻炼:

  • 执行顺序,
  • 平均等待时间,
  • 平均完成时间
e.g execution order 4433>54>534>12>73. 
average completion time = 6132/5
(556+(556+424)+(556+434+123)+(556+424+123+432)+(556+424+123+432+423)) / 5

average wait time = 4174/5
(0+556+(556+424)+(556+424+123)+(556+424+123+432)) / 5

最后的结果是将这些数字中的每一个分配给一个唯一的变量,我以后可以用它来进行数学运算

od -c Process.dat 的输出

0000000   0   1   0   1   3   4       7   5   6       4   4   4   3  \r
0000020  \n   0   1   0   1   3   6       7       4   2  \r  \n   0   1
0000040   2   1   4   5       1   6       1  \r  \n   0   2   1   2   4
0000060   4       7   2       3  \r  \n   0   2   2   1   4   5       7
0000100   1       5   5
0000104

值不同,因为我使用示例文件来检查示例输出的输出,但仍应以相同的方式操作

示例文件和输出

010134 756 443
010136 7 42
012145 16 1
021244 72 3
022145 71 55

outputs:
avg comp = 4141/5
avg wait = 3149/5

【问题讨论】:

  • 如果您需要数组的数组,请转向更高级的编程语言。 Perl、Python、Ruby...
  • specific bit of work 您是否特别必须创建不同的变量,或者您想稍后使用它们?这些变量毫无意义。
  • “使以后需要的数学变得更容易”——你能说明你在没有之前没有这个操作的情况下尝试做数学时遇到的具体问题吗?
  • 仍然需要知道您期望结果变量的样子;这看起来更像XY problem,在这种情况下,如果您可以提供一些示例来说明您计划如何在“稍后需要的数学”中使用这些变量,则可能会更有意义;此外,这个“稍后需要数学”......这将在while 循环中逐行完成,以便可以为每行重复使用 3x 变量,或者您是否需要明确保存每个一组单独的变量中的值行?
  • (我赞同 chepner 的说法——如果你真正的意思是“需要使用 Linux 上可用的开箱即用工具”,f/e,这意味着你有 awk,并且对于这类问题,awk 比 bash 好得多;此外,Python 就像 bash 在现代发行版上一样开箱即用)。

标签: bash shell


【解决方案1】:

假设/理解(来自 OP 的 cmets):

  • 输入文件有3列:index timeburst timeid number
  • 每一行输入都包含N 顺序运行进程之一的详细信息(其中N 是输入文件中的行数)
  • 所需的输出是SUM/N 形式的字符串,其中SUMN 进程的执行/等待burst times 的总和(也就是文件中的行数)
  • 附加输出是ID1&gt;ID2&gt;ID3&gt;...&gt;IDN 形式的字符串,它只是id number 列中值的串联
  • OP 已声明这些输出不会用于后续的“数学运算”
  • 听起来(对我来说)这个练习的全部目的是生成一些表示(输入的)聚合元数据的文本输出

一个bash想法:

sum=0
count=0

comp_total=0
wait_total=0

exec_order=
pfx=

while read -r index burst id
do
    exec_order+="${pfx}${id}"
    pfx='>'

    (( count++ ))

    wait_total=$((wait_total + sum))
    sum=$((sum + burst))
    comp_total=$((comp_total + sum))

done < Process.dat

#echo "comp_total : ${comp_total}"
#echo "wait_total : ${wait_total}"
    
comp_avg="${comp_total}/${count}"
wait_avg="${wait_total}/${count}"

echo "exec_order : ${exec_order}"
echo "comp_avg : ${comp_avg}"
echo "wait_avg : ${wait_avg}"

这个输出:

exec_order : 4433>54>534>12>73
comp_avg : 6132/5
wait_avg : 4174/5

【讨论】:

  • 非常感谢您的帮助,但是我似乎无法让执行命令输出正确的输出,而是输出“32c_order : 4433”
  • 我也得到 /4 而不是 /5
  • 假设您将代码剪切并粘贴到您的环境中,我将假设您的输入文件来自 Windows 环境,因此具有 Windows/DOS 行结尾 (\r\n);如果od -c Process.dat 显示字符\r,那么您 在文件中有Windows/DOS 行结尾;删除行尾的一种简单方法是在运行脚本之前运行 dos2unix Process.dat(再次运行 od -c Process.dat 以验证 \r 字符已消失);这(\r 字符的存在)也可以解释错误计数(4 而不是5
  • 如果仍有问题,请使用od -c Process.dat的完整输出更新问题
  • 您的 od-c 输出显示文件有 Windows/DOS 行结尾 (\r\n) 和 no 行结尾为最后一行; printf "\n" &gt;&gt; Process.dat 在文件末尾添加\n;运行dos2unix Progress.dat(应该只需要运行一次)删除\r字符;对您的实际输入文件进行这些更改并再次运行;如果仍然有问题打开一个新问题,请提供示例输入、您尝试过的代码、您的代码生成的错误输出和预期的代码;对原始问题的所有更改/添加,这个当前的问答变得过于冗长和混乱
猜你喜欢
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多