Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I've got a script in bash. Unfortunately I've to multiplicity all entries in array (witch have 4000 entries) with a number <0. bash dosen't that. Consequently I want translate the bash array into awk. Maybe it would be better to use awk in the hole script, but I have no experience in awk.
There are plenty of people here who I'm sure have great expertise with both BASH and AWK and could do it I'm sure.
You're asking for a handout. Instead post what you have in BASH and at least try to start with AWK.
Personally I'd suggest using a program. I don't see AWK to be a scripting language, but instead a command.
My other suggestion is that since you've leaned that AWK supports the capability to multiply negative numbers, then why not stage one calculation in AWK as your first try and then look to expand from that.
I'm sure reviewers would be very pleased to see something like:
Here's my BASH script (use [code] tags by the way)
Here's one calculation that I converted to AWK
Any suggestions how I would apply that concept to an entire array? Do I just step through the list, or use array indexes?
#!/bin/bash
ZS=($(find . -name "*.plt"))
i=1
Solutiontime=$((3.17/10000000))
for Dataname in ${ZS[@]}
do
Cut=${Dataname:13}
Timesteps=${Cut:0:${#Cut}-4}
Array[i]=$Timesteps
i=$((i++))
p=$((i++))
done
Amount=$p
for ((i=1;i<10;i++))
do
Array[i]=${i}00
done
for ((i=1;i<$Amount+1;i++))
do
Array[i]=$((${Array[i]}*$Solutiontime))
done
Array[0]=Solutiontime
So I am not 100% on what the actual issue is, however, I see glaring problems in the current bash solution that do not include the use of decimal numbers.
Also, I am not really following the logic either
Code:
# below finds all files from current folder and below that have files of any type (including directories)
# that end in '.plt' ... so first issue I see is no limiting to files of type file only
ZS=($(find . -name "*.plt"))
# set 'i' variable to 1, but later you comfortably use standard for loop notation
i=1
# obviously the below will not work and either the bc or awk option can be used for correct calculation
Solutiontime=$((3.17/10000000))
# no double quotes around array value can cause word splitting in unwanted ways
for Dataname in ${ZS[@]}
do
# remove the first 13 characters of the data name ... would be nice to know what that translates to
Cut=${Dataname:13}
# Cut is never used again, why not simply use 'Dataname' variable
# Timesteps=${Dataname:13:${#Dataname}-17}
Timesteps=${Cut:0:${#Cut}-4}
# Set i'th element of array to 'Timesteps' value
Array[i]=$Timesteps
# Here it get tricky. Set 'i' equal to the value of 'i' and then increase by 1 (so on first loop it will still be 1
i=$((i++))
# Now assign current value of 'i' (still 1) to 'p' and increase 'i' ... now 'i' is 2 on first loop
p=$((i++))
# Even though 'i' is at the correct value by this point, you can see a redundant step
done
# Set 'Amount' to final value of 'p'
Amount=$p
# The loop below now overwrites the first 10 elements of 'Array'
# Again, not following the logic here
for ((i=1;i<10;i++))
do
Array[i]=${i}00
done
# This array loop has the ability to step off the end of the array ... not sure why we would want to do that
# It also (again) overwrites at least the first up to 10 values which will now have been saved into 'Array' 3 times
for ((i=1;i<$Amount+1;i++))
do
# Again use bc or awk for non-integer math
Array[i]=$((${Array[i]}*$Solutiontime))
done
# Not sure why zeroth element needs to be this value
Array[0]=Solutiontime
As you can see, I have many more questions than answers at this point in time
So I am not 100% on what the actual issue is, however, I see glaring problems in the current bash solution that do not include the use of decimal numbers.
Also, I am not really following the logic either
I concur and my recommendation is that the OP consider working through the form of a single calculation they wish to attain, because of the following additional points they've made.
Quote:
Originally Posted by Ambalo
Sorry for my "low skill questions", but I use bash since 10 am.
Quote:
Originally Posted by Ambalo
Maybe it would be better to use awk in the hole script, but I have no experience in awk.
You wish to multiply one or more negative numbers. They are integers, or floating point numbers? I think you wish to multiply floating point numbers and you say one of them could be negative. I'd solve the general problem of multiplying two floating point numbers of any sign and once you understand how to do that in any script or language you end up using, then look to improve this into dealing with all elements of an array.
I think AWK can better deal with the floating point calculations and BASH can better deal with the array manipulations. So I'd learn how to do the calculations using AWK and write a BASH script to manage the processing of each data point.
I have 4000 datafiles who exported from a fluid dynamic program. The filename are "TecN210500-xxxxx.plt". "xxxxx" are the iteration number. And i need the iteration number to calculate the solution time of my simulation. The first loop manipulated the filename, so that only the "xxxxx" are written in the array. The first 9 filenames like "TecN210500-0100.plt"; "TecN210500-0200.plt".... Furthermore the variable "p" is needed, because after every loop, the variable i equal 1.
The second loop delete the first zero because bash can't calculate with numbers with a leading zero. The variable "amount" counts the datafiles for the last loop.
The last loop multiply every entry of the array with the "Time Step" of the simulation. After doing that, I want write these information into the datafile "TecN210500-xxxxx.plt". The first line in the datafile like "Static Pressure". So I write in the first line of the array "Solutiontime".
Hope it's clearer now and sorry for my bad english....
I don't want multiply negativ numbers. Sorry for misunderstanding.
The math operations are:
100 * 3.17*10^-7
200 * 3.17*10^-7
300 * 3.17*10^-7
........
Input data example (overall 4000 datafile):
TecN210500-0100.plt
TecN210500-0200.plt
TecN210500-0300.plt
TecN210500-0400.plt
......
0100 are the iteration number. The first loop extract the "0100" from the filename. The second loop "delete" the leading zero -> "100". The last loop multiply with the time step -> "100 * 3.17*10^-7"
I agree with rtmistler that you should solve for a single solution first as the looping part is a no-brainer.
I see now the part of the filename you wish to extract and whilst there are other ways to do this I still see issues with the logic of how you have gone about some things.
I was going to say that the second loop does not remove the leading zero from your data, but I now see that your solution to do this was to overwrite the first 10 elements.
This method obviously works, as long as the format never changes in the future.
I am slightly perplexed on a point though, if all the file names are uniform and are always in amounts of 100 up to 4000, why not just perform the task in a for loop from 100 to 4000 step 100?
Unless I have missed that these numbers may change I am not seeing why you need to go through all the trouble of stripping the file names and so on.
If the above is correct, this becomes a trivial loop where awk could then be used to perform the task:
Code:
awk 'BEGIN{for(i = 100; i <= 4000; i+=100)array[j++] = i * (3.17 * 10**-7)}'
This simply creates the array so whatever it is you want to do with it is up to you.
I was going to say that the second loop does not remove the leading zero from your data, but I now see that your solution to do this was to overwrite the first 10 elements.
This method obviously works, as long as the format never changes in the future.
The first elements are always the same.
Quote:
I am slightly perplexed on a point though, if all the file names are uniform and are always in amounts of 100 up to 4000, why not just perform the task in a for loop from 100 to 4000 step 100?
Not every simulation had 4000 steps. That's why I count the amount of datafile.
Quote:
Unless I have missed that these numbers may change I am not seeing why you need to go through all the trouble of stripping the file names and so on.
The problem is the export of the fluid dynamic program. The solution time are not in the export datafile so I have to go a long way round with the iteration steps.
The time steps are not from 100 to 4000 with step 100. There are 100 * 4000 iterations. Every export have 100 iterations included. And 4000 export files are created. Thanks for the awk array. Actually really simple. I will try with your posted code.
Assigning this to another array: you must enclose it with ` ` or $( ) in order to get a string/list, then enclose it by ( ) to feed the list into an array.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.