0

I am writing a script in bash to deal with some text files, also containing numbers. I have created an array variable in with 45 positions filled with numbers. I have this text file (delimiter is actually a '|', not a comma) with 5 fields/columns and 45 lines. I would like to add a 6th column, and write the nth value of the array on each nth line of the file.

My original text file, with:

 61537000|COO|DI|VMD|2018-01-08 00:00:00   
 61537000|COO|DI|VMD|2018-01-09 00:00:00   
 61537000|COO|DI|VMD|2018-01-10 00:00:00   
 61537000|COO|DI|VMD|2018-01-11 00:00:00   
 61537000|COO|DI|VMD|2018-01-12 00:00:00
 ...
 61537000|COO|DI|VMD|2018-02-21 00:00:00

My array variable is stored in qy. echo ${qy[*]} gives me:

133.7545755174117347 197.5730453102068415 211.0612457141076671 195.3965252988823307 155.9141492798344956 122.0765862336716795 109.3807402580878840 100.1258594727256394 118.3713165600757955 129.9118732920391577 130.2183465952591614 108.3783455600275339 87.3744866455706415 74.6811189513075407 67.2786196847537834 66.6486466128231307 75.5263825809798786 79.7579752859345201 76.7748478701627372 75.7971233334776102 75.5218971041520397 74.3644957571369167 74.7302279790034398 82.9013111977886133 107.8462461297641418 109.3922469923296476 87.2584880672884534 74.3278359110118687 66.8273524401225775 62.9054376472748469 59.2471567250619217 55.4465232890134493 54.9324477319027615 55.0268189192084034 50.3969437024658000 48.2808157236208981 49.8788627643603767 50.7025436995365588 52.5391775713757207 51.6024683921895763 66.5341261816728136 73.3342955766798011 68.3585064456764055 69.1125302235501069 75.0594939607898664

Desired output file:

 61537000|COO|DI|VMD|2018-01-08 00:00:00|133.75
 61537000|COO|DI|VMD|2018-01-09 00:00:00|197.57  
 61537000|COO|DI|VMD|2018-01-10 00:00:00|211.06
 61537000|COO|DI|VMD|2018-01-11 00:00:00|195.39
 61537000|COO|DI|VMD|2018-01-12 00:00:00|155.91
 ...
 61537000|COO|DI|VMD|2018-02-21 00:00:00|122.07

I have successfully used while read line do; ... done < file with cut -d '|' -f6 to read from file, but apparently there is not an analogous while write sort of straightforward loop to write in it, is there? Any help would be very much appreciated.

3 Answers 3

0

Pure bash method. Since the number of elements in $qy is the same as the number of lines in file, a for loop should work, using read inside the loop:

for f in ${qy[*]}; do read x; printf '%s|%.2f\n' "$x" "$f"; done < file

If for some reason printf isn't behaving, it can be done with echo and parameter substitution:

for f in ${qy[*]}; do read x; echo "$x|${f%%??????????????}"; done < file
2
  • Very clear logics. Thank you a lot. Indeed, printf did not work in the first option (invalid number error again, as in the first answer). But the second option worked just as desired. I just added >> outfile so that to append in each loop: for f in ${qy[*]}; do read x; echo "$x|${f%%??????????????}" >> outifle; done < file
    – ouranos
    Commented Apr 2, 2018 at 12:09
  • @ouranos, Glad to help. Since the loop only outputs to one file, consider instead using for f in ${qy[*]}; do read x; echo "$x|${f%%??????????????}"; done < file > outfile.
    – agc
    Commented Apr 2, 2018 at 18:01
0

There's good ol' paste:

printf '%.2f\n' "${qy[@]}" | paste -d'|' textfile -
 61537000|COO|DI|VMD|2018-01-08 00:00:00|133.75
 61537000|COO|DI|VMD|2018-01-09 00:00:00|197.57
 61537000|COO|DI|VMD|2018-01-10 00:00:00|211.06
 61537000|COO|DI|VMD|2018-01-11 00:00:00|195.40
 61537000|COO|DI|VMD|2018-01-12 00:00:00|155.91

(I only copied the first 5 entries, for brevity).

7
  • Worked perfeclty! Thank you. However, I can only have 2 characters after the dot (two decimals), as in the "desired output" example above. Any suggestions?
    – ouranos
    Commented Apr 2, 2018 at 1:21
  • When I substitute the %s by %.2f I get an invalid number error and the 6th column is filled with 0,00s.
    – ouranos
    Commented Apr 2, 2018 at 1:22
  • @ouranos apologies - I missed that requirement. Please see updated answer. Commented Apr 2, 2018 at 1:45
  • I really appreciate your effort Nasir, but your solution writes 7 characters after the space, and not the number with 2 characters after the comma. This is a problem because for numbers <100 I get 3 decimals and for numbers <100 I get 3 decimals. Thank you a lot for your response though.
    – ouranos
    Commented Apr 2, 2018 at 1:46
  • @steeldriver no worries. This was actually the first thing I tried as this syntax is common to other languages. However, I get the error printf: 44.7741723630836868: invalid number when using %.2f as I mentioned earlier. The 6th column then is filled with a bunch of zeros in the format 0,00 (that is a comma separating decimals). Any clue of what may cause this? Many thanks.
    – ouranos
    Commented Apr 2, 2018 at 1:52
0

step1

sed -r  "s/\s+$//g" orgial_textfile| awk '{print $0"|"}' >>orginal_final_textfile

Step2

save the array variable in need_copy_textfile

sample need_copy_textfile format will be

133.7545755174117347
197.5730453102068415
211.0612457141076671
195.3965252988823307
155.9141492798344956
122.0765862336716795
109.3807402580878840
100.1258594727256394
118.3713165600757955
129.9118732920391577
130.2183465952591614
108.3783455600275339
87.3744866455706415
.
.
.

75.0594939607898664


awk '{print substr($1,1,6)}' need_copy_textfile >> need_copy_textfile_final.txt

step3

Now combine above 2 files to get required result

paste orginal_final_textfile need_copy_textfile_final.txt | sed -r "s/\t+//g" 

Sample output

61537000|COO|DI|VMD|2018-01-08 00:00:00|133.75
61537000|COO|DI|VMD|2018-01-09 00:00:00|197.57
61537000|COO|DI|VMD|2018-01-10 00:00:00|211.06
61537000|COO|DI|VMD|2018-01-11 00:00:00|195.39
61537000|COO|DI|VMD|2018-01-12 00:00:00|155.91

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.