I'm totally new at this, so help will be appreciated.
I have a directory with a bunch of files in it. The files are named xinteger_yinteger_zinteger.vtk (eg, x3_y0_z-1.vtk). I want to read the filenames and then assign the integers to variables that I then can use in expressions. So, for x3_y0_z-1.vtk, I want to assign xvariable=3, yvariable=0, zvariable-1.
I assume that I have to use one command to assign a filename to a string and then something like printf to parse the string. But that's as far as I've gotten.
Assuming that you're using a POSIX conforming shell (such as ksh or bash), the following seems to do what you want:
#!/bin/ksh
for file in x*_y*_z*.vtk
do
printf "%s\n" "$file" | (
IFS="xyz_." read x xvariable x yvariable x zvariable x
printf "Processing file %s: x=%s, y=%s, z=%s\n" "$file" \
"$xvariable" "$yvariable" "$zvariable"
)
done
When the above script is run in a directory containing the files:
Great! You are in for learning the most interesting thing there is the world: shell programming in the Unix environment!
(Well, now that i jog my memory really hard, i have to admit there are a few other interesting activities too in life - but nothing is that rewarding, i promise. ;-)) )
You won't need "printf", but i appreciate you doing your own thinking. Lets go through it step by step:
First, we want to read in all the filenames in a directory. We do that in a loop:
#! /bin/ksh
typeset file=""
ls /path/to/your/dir |\
while read file ; do
print - "we have found file ${file}"
done
exit 0
We define a variable "file" and in every pass of the loop this variable is set to a new value, cycling through all the file names in your directory. Once we are through it the loop ends and so does your script. The "print"-line is in there only for your edification: control if all the files you want to process are indeed shown and if every file you wanted to be left out is indeed left out. If this is not the case you might want to change your filemask, for instance:
ls /path/to/your/dir/*certain-extension |\
while read file ; do
otherwise you are ready to proceed: Now that we have the filename available we are ready to dissect it. In the shell this is done by so-called "variable expansion". You should indeed read a good book about shell programming which will cover this perhaps in a chapter of its own. Its a most often neglected art but one of the differences between the pros and the crowd. The reason: it might look awkward at first, but it is blazingly fast. You might need several lines, but these are executed faster by an order of magnitude than a single line calling some external utility.
Basically you can cut off patterns from a string from the front or the end. The first one is really easy:
file="x3_y0_z-1.vtk"
print - ${file%%.vtk}
You will see that the extension ".vtk" is removed. "%%" means: take the variables ("file") content and cut off from the end everything that matches the pattern (".vtk") and display what is left over. Let us put that into our script:
#! /bin/ksh
typeset file=""
ls /path/to/your/dir/*vtk |\
while read file ; do
file="${file%%.vtk}"
print - "we have now filename ${file}"
done
exit 0
Again, the "print"-statement serves no other purpose than to let you see what we have achieved so far. Now, the main work: let us first chop off "z". For this we use an "inverted %%", the "##". It removes a pattern beginning from the start of a string. Because we know that the value we want to know is at the end, following a "z", we can simply remove everything up to this letter:
file="x3_y0_z-1"
print - ${file##*_z}
The "*" means the same as in "ls -l *": any number of characters in any length. Let us put that into the script:
Likewise we are ready to get the other variables: first, we cut off the already extracted z-part, then we apply the same logic as before for the y-part:
Try these things on the command line. You can also play around with the patterns and the variable contents to get a feeling for this. Finally we put that into the script again:
I am sure by now you don't my explanations any more and you surely are eager to apply your newfound knowledge on the last part of the problem. Have fun with shell programming.