LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-22-2010, 10:46 AM   #1
alos31
LQ Newbie
 
Registered: Apr 2010
Posts: 12

Rep: Reputation: 0
Need help with array of images in Bash


Hi I am a newbe to bash programming and need some help. I am building a pipeline for image processing. I would like to be able to take the png images in a folder and pass them to clusterImage.pl once that is done I would like to then pass the outputted file to seperateObjects.pl the outputted file is of the same name but has kmeansOutput.all.matrix attached to the end. Below is what I have so far, but it is not working.
Any help would be greatly appreciated. Thank you

#!/bin/bash
#This script will take in an image and a matrix file.
#The output will be an image and a matrix file.

list=`ls *.png`
for i in $list
do
$file="./$list"
$image_array = $list
echo $file
#Cheching to see if the file exists.
for((j=0;j<=i;j++))
do
if [ -e image_array[j] ]; then
echo $file
echo "Begining processing"
#Take in an image and create a matrix from it.
perl clusterImage.pl SampleImage.png
#Take in a matrix and draw a picture showing the centers of all
#of the colonies.
perl seperateObjects.pl SampleImage.png.kmeansOutput.all.matrix
echo "Ending processing"
else
echo "There is an issue"
fi
done
done
 
Old 06-22-2010, 02:02 PM   #2
penguiniator
Member
 
Registered: Feb 2004
Location: Olympia, WA
Distribution: SolydK
Posts: 442
Blog Entries: 3

Rep: Reputation: 60
Code:
list=`ls *.png`
for i in $list
do
$file="./$list"
There are a couple of problems in just your first few lines of code. First, you are trying to create a list, which itself is not a problem. But your syntax will not result in a list of png files as you expect. The Arrays section of the bash manual shows how to create lists.

The way you are trying to operate on the values stored in the list in your for loop is also flawed. A list variable's values may be accessed using subscripts. Two particular subscripts will let you iterate over all the items in a list: * and @. The same section of the bash manual will explain this.

The next problem is related to the second one. You appear to by attempting to assign a single item of your list to the variable file, but without using a subscript and treating it as a single filename. This simply will not work as you expect. Also, the assignment statement itself is flawed, because you use a $ to refer to the variable file. The dollar sign is only used with a variable name when you want access to the value stored in the variable, not when you are manipulating the variable itself.

If I understand your logic correctly, you want to create a list of existing png files in the current directory. Then, with each file in the list you want to echo the filename and process it with two Perl scripts. I'm not familiar with the Perl script you refer to in your code. But there appears to be a problem with your logic. You have a second for loop nested inside the first one which refers to the i variable of the outer loop. You treat i as a number, but it will be a string (once you fix your list creation code). Therefore, the code: j<=i will be an ambiguous comparison at best.

The test in your if statement does not dereference the item in your image_array variable correctly. The bash manual section about arrays should clear this up.

I'm not sure why you are trying to create multiple copies of your list. You should be able to do all of the work with your list variable. It looks to me like you may be confusing some of Perl's syntax with Bash's. Perl scalar variables are always referenced with: $var. Bash variables are only referenced that way when getting the data stored in them. Otherwise the $ is left off.
 
Old 06-22-2010, 02:03 PM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Hmm. Kind of confused here. Almost too many issues to mention.

First of all, please use [code][/code] tags, to preserve the formatting of the code. It's hard to follow the script without indenting. I had to copy it to a file and re-format it to figure it out.

Now, from the top

Code:
list=`ls *.png`   #not so good
1. $(..) is recommended over `..`
2. You shouldn't need to use ls to create a list of files. Bash has it's own globbing ability.

Code:
$file="./$list"   #wrong
I'm not sure what you're trying to do here. This just appends ./ to the front of the first entry in the list of files you created earlier. Not to mention that you never, ever use $ when setting a variable.

Code:
$image_array = $list  #wrong!
Is this supposed to be the place where you populate the array? Because this is exactly NOT how to do that in bash.

Code:
for((j=0;j<=i;j++))   # not ok
(edit: I just noticed that this is wrong too, since $i is not an integer)

Anyway, there's a more convenient way to loop through array elements in bash.

Code:
for j in ${!image_array[@]} ; do   #better
${!array[@]} outputs a list of all existing array indexes.

Code:
if [ -e image_array[j] ]; then   #wrong
You do however use $ when you need to fetch the value of a variable (or array element). Also you should generally quote them in order to protect any spaces in the strings from word breaking.

Code:
if [ -e "${image_array[$j]}" ]; then  #right
But why do you need to check if the file exists, when you got the filename from ls in the first place?

Code:
perl clusterImage.pl SampleImage.png
Neither of your perl commands has any input from the array list. I suppose that may be because you're just in testing though.

Anyway, assuming I understand your needs, here's a basic framework of what you should be doing. To tell the truth, I don't see any need at all for an array here, so first of all, here's just a simple loop.

Code:
for i in ./*.png; do

     echo "$i"
     perl clusterImage.pl "$i"  #$i is the input file
     perl seperateObjects.pl "$i.kmeansOutput.all.matrix"  # the input is $i with the string attached

done
This is assuming that the first script modifies the output filename itself and places it in the working directory.

But if for some reason you really need to use an array, then you just make a simple modification to populate and loop through the array. Probably something like this:

Code:
image_array=( *.png )

for i in ${image_array[@]}; do

     echo "$i"
     perl clusterImage.pl "$i"  #$i is the input file
     perl seperateObjects.pl "$i.kmeansOutput.all.matrix"  # the input is $i with the string attached

done
...although details like the exact filename format and the perl command input might be important.

Last edited by David the H.; 06-22-2010 at 02:22 PM. Reason: minor fix, addendum
 
Old 06-22-2010, 02:14 PM   #4
penguiniator
Member
 
Registered: Feb 2004
Location: Olympia, WA
Distribution: SolydK
Posts: 442
Blog Entries: 3

Rep: Reputation: 60
The only problem with the corrected logic about existing files is that when you don't use ls to create your list and you use a globbing pattern, if the pattern does not match any files, the pattern itself will populate the list. This will make checking for filename existence necessary.
 
Old 06-23-2010, 01:24 AM   #5
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Quote:
Originally Posted by penguiniator View Post
... if the pattern does not match any files, the pattern itself will populate the list. This will make checking for filename existence necessary.
Try 'shopt -s nullglob'. Run 'help shopt' for more info.
 
Old 06-23-2010, 07:35 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Yep, and there's also a "failglob" option, if you'd prefer to have it spit out an error message instead.
 
Old 06-23-2010, 09:16 AM   #7
alos31
LQ Newbie
 
Registered: Apr 2010
Posts: 12

Original Poster
Rep: Reputation: 0
Thank you everyone!
 
Old 06-23-2010, 11:04 AM   #8
penguiniator
Member
 
Registered: Feb 2004
Location: Olympia, WA
Distribution: SolydK
Posts: 442
Blog Entries: 3

Rep: Reputation: 60
Didn't know about nullglob. That will come in handy.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash array Add function example using indirect array reference as function argument bobywelsh Programming 10 07-05-2010 04:44 AM
[bash] indirect array reference to array with values containing spaces Meson Linux - Software 9 06-04-2010 09:38 PM
bash: use file as input into array, parse out other variables from array using awk beeblequix Linux - General 2 11-20-2009 10:07 AM
Bash Variable Array, Trying to add another value into the array helptonewbie Linux - Newbie 6 03-02-2009 11:18 PM
php upload an array of images spoody_goon Programming 3 05-22-2005 11:42 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration