-1
#! /bin/bash
readarray rows < Process.dat

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

done

echo "$row1"

the output for this code is 10110 556 4433, I have tried using the same piece of code again changing the variables of "rows" and "row" however there is no ouput when i do this, How can i split up the variable "row1" into the 3 seperate numbers each assigned to a different variable, e.g row1_1 = 10110, row1_2 = 556, row1_3 = 4433

the input file consists of 5 rows and 3 columns of numbers:

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

The columns represent index time, burst time and id number respectively.

I need to work out:

  • execution order,
  • average wait time,
  • average completion time
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

the endgame is to have each of these numbers assigned to a unique variable that I can later use to do math operations

output from 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

the values are different because i am using the example file to check outputs against the example outputs but should still act in the same way

example file and outputs

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

outputs:
avg comp = 4141/5
avg wait = 3149/5
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    If you need arrays of arrays, move to a more advanced programming language. Perl, Python, Ruby... – choroba Dec 20 '21 at 17:30
  • sadly I have to use Bash for this specific bit of work –  Dec 20 '21 at 17:32
  • Hi, look at https://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash – script0 Dec 20 '21 at 17:33
  • same response to your earlier question (since deleted) on this same topic ... review [how do I ask a good question](https://stackoverflow.com/help/how-to-ask) and then update the question accordingly; in particular, provide sample input, the code you've tried, the (wrong) output generated by your code and the (correct) desired output; also, does the input file consist of just a single row or are there multiple rows in the input file ... and if the answer is 'multiple rows' then show the expected output for a file with multiple rows (eg, load all rows/columns into a single array?) – markp-fuso Dec 20 '21 at 17:38
  • 1
    `specific bit of work ` Do you specifically _have to_ create different variables, or do you want to use them variables later? The variables just make no point. – KamilCuk Dec 20 '21 at 17:40
  • I want multiple variables to use later as it makes the math needed later significantly easier –  Dec 20 '21 at 17:41
  • @markp-fuso I think I have now updated to provide all relevent info –  Dec 20 '21 at 17:47
  • 1
    "Makes the math needed later significantly easier" -- could you show the specific problem you run into trying to do the math _without_ this operation preceding? – Charles Duffy Dec 20 '21 at 17:50
  • 1
    still need to know what you expect the resultant variable(s) to look like; this is looking more like an [XY problem](https://xyproblem.info/) in which case it may make more sense if you can provide some examples of how you plan on using these variables in 'the math needed later'; also, this 'math needed later' ... will this be done on a line-by-line basis within a `while` loop such that the 3x variables can be re-used for each line or do you need to explicitly save each line of values in a separate set of variables? – markp-fuso Dec 20 '21 at 17:50
  • Why do you *need* to use `bash`? – chepner Dec 20 '21 at 17:50
  • 1
    (I echo what chepner says -- if what you really mean is "need to use out-of-the-box tools available on Linux", f/e, that means you have awk, and awk is _much_ better than bash for this class of problem; moreover, Python is just as out-of-the-box as bash is on modern distros). – Charles Duffy Dec 20 '21 at 17:51
  • 1
    `values=( $( – markp-fuso Dec 20 '21 at 17:57
  • @chepner I need to use Bash because i have been asked to, i agree that this would be mush easier with pretty much any language, because i am more familiar with other languages. But my tutor has insisted i use bash because i am pretty much new to bash and it's syntax –  Dec 20 '21 at 17:57
  • Your tutor is making you waste your time. There are plenty of `bash`-appropriate tasks they could assign to help you learn `bash`. This is not one of them. – chepner Dec 20 '21 at 17:58
  • update the question with a sample of the 'math'; need to know if the 'math' can be performed in the same `while` loop used to read the file (ie, variables can be re-used for each pass through the loop), or if the 'math' is done outside the loop thus requiring each row/column value is stored separately; also, do the results of the 'math' need to be stored in other variables or just dumped to stdout (eg, to console, to file)? – markp-fuso Dec 20 '21 at 18:02
  • `I want multiple variables to use later ` Why not just use the actual data, instead of making the variables. It's just a means to an end, omit that part. – KamilCuk Dec 20 '21 at 18:23
  • @KamilCuk it needs to work with other .dat files in the same format, this is just a sample file provided for the work –  Dec 20 '21 at 18:24
  • `need to work out: execution order, average wait time, average completion time` Use awk. Do not use bash at all. Solve one problem at a time, it will be easier. For execution order, seems like just `sort` will be enough. Or, Isee, use `cut` with `paste -sd '>'` to join lines with `>`. How do you calculate "completion time" and "wait time" from the input data? – KamilCuk Dec 20 '21 at 18:25
  • 1
    @KamilCuk as stated in a previous comment I have to use Bash as this is work set by my tutor –  Dec 20 '21 at 18:27
  • Then start with https://mywiki.wooledge.org/BashFAQ/001 . Do not set variables to be used later. Read the file, and while reading it, parse it. – KamilCuk Dec 20 '21 at 18:28
  • 1
    `bash` only does 'integer' math, eg, `echo $((5/2))` ==> `2`; to work with reals/floats you'll need to use some other command and/or language, eg, `bc`, `awk`, `perl`, etc, etc, etc; and while you can store the results (eg, `2.5`) in a `bash` variable, any follow-on 'math' will, again, need to use other commands/languages – markp-fuso Dec 20 '21 at 18:34
  • @markp-fuso I don't need the float values I can keep in the form of a fraction –  Dec 20 '21 at 18:37
  • even for the 'simple' stuff you've asked for - `average completion time = 6132/5` / `average wait time = 4174/5` - you haven't told us how you came up with the values `6132` and `4174` (assuming these are somehow derived from the sample inputs); you've stated you don't know `bash` ... ok, fair enough ... everyone commenting in this thread knows `bash` but ... you have to give us the details we need to help you – markp-fuso Dec 20 '21 at 18:39
  • @markp-fuso added now –  Dec 20 '21 at 18:44
  • saving `6132/5` as a 'fraction' means saving it as the string `6132/5`; you then mention you want to `later use to do math operations` ... are these 'math operations' also going to be done in `bash`, or some other language? the reason I ask is that `6132/5` cannot be used by `bash` for 'math operations' so we're right back to the same, repeated question ... what is the actual 'math' you're talking about? generating the string `6132/5` is (relatively) easy to do but a waste of time if you won't be able to use it later in your (`bash`) script – markp-fuso Dec 20 '21 at 19:09
  • @markp-fuso I just need to generate the string as it won't be used in further calculations, the math operations later will only use the data in the file not the average times –  Dec 20 '21 at 19:10
  • what do you mean by `need to work out: execution order`? the comment reads: `execution order 4433>54>534>12>73` ... which appears to be the order in which the data current exists in `Process.dat`; are we supposed to pre-sort the file based on some (as yet) undefined order? are we supposed to save the sequence of `id` values and if so, in what form? a single variable? an array? – markp-fuso Dec 20 '21 at 19:13
  • @markp-fuso as far as I am aware the execution order is just the order in which they appear in the file as the example i was given is as such, the output of the execution order would also just be a string of "4433>54>534>12>73" –  Dec 20 '21 at 19:17

1 Answers1

1

Assumptions/understandings (from OP's comments):

  • input file has 3 columns: index time, burst time and id number
  • each line of input contains details for one of the N sequentially run processes (where N is the number of lines in the input file)
  • desired output are strings of the form SUM/N where SUM is the sum of execution/wait burst times for the N processes (aka number of lines in file)
  • additional output is a string of the form ID1>ID2>ID3>...>IDN which is simply a concatenation of the values in the id number column
  • OP has stated these outputs will not be used in follow-on 'math operations'
  • it sounds (to me) like the whole purpose of this exercise is to generate some textual output representing aggregate metadata (of the inputs)

One bash idea:

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

This outputs:

exec_order : 4433>54>534>12>73
comp_avg : 6132/5
wait_avg : 4174/5
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • Many thanks for your help, however I can't seem to get the exec order to output the correct output instead outputting "32c_order : 4433" –  Dec 20 '21 at 19:56
  • I also get /4 instead of /5 –  Dec 20 '21 at 20:05
  • Assuming you cut-n-pasted the code into your environment, I'm going to assume your input file came from a Windows environment and thus has Windows/DOS line endings (`\r\n`); if `od -c Process.dat` shows the character `\r` then you ***do*** have Windows/DOS lined endings in the file; one simple method to remove the line endings is to run `dos2unix Process.dat` prior to running your script (run `od -c Process.dat` again to verify the `\r` characters are gone); this (existence of `\r` characters) may also explain the miscount (`4` instead of `5`) – markp-fuso Dec 20 '21 at 20:06
  • if still having problems, update the question with the complete output from `od -c Process.dat` – markp-fuso Dec 20 '21 at 20:09
  • dos2unix fixed the exec order however the outputs are still 4 rather than /5 –  Dec 20 '21 at 20:12
  • I'm guessing the input file is missing a line ending (`\n`) for the last line; again, update the question with the complete output from `od -c Process.dat` or edit the file and make sure there's a line ending on the last line – markp-fuso Dec 20 '21 at 20:15
  • @Fravadona there are a couple different ways to do the 'math'; I opted to mimic OP's summations (in the question); are you getting something other than `6132/5` and `4174/5`? – markp-fuso Dec 20 '21 at 20:19
  • the actual values may be different as i did the math mentally however the calculations to get there should still be correct –  Dec 20 '21 at 20:21
  • My formula was wrong but I noticed that you can just set `wait_total` to the value of `comp_total` before updating `sum` and `comp_total` – Fravadona Dec 20 '21 at 20:27
  • @markp-fuso when using the example data i don't get the example outputs but I'm not sure why my com avg = 3149/5 and wait avg = 2298/5. (the example data is given in the original question now). do you know why? –  Dec 20 '21 at 20:44
  • 1
    your `od-c` output shows file has Windows/DOS line endings (`\r\n`) and ***no*** line ending for the last line; `printf "\n" >> Process.dat` to add a `\n` on the end of the file; run `dos2unix Progress.dat` (should only need to run once) to remove the `\r` characters; make these changes to whatever is your actual input file and run again; if still having problems open a new question, provide sample input, code you've tried, wrong output generated by your code and expected code; this current Q&A is getting too drawn out and confusing by all the changes/additions to the original question – markp-fuso Dec 20 '21 at 20:51