LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices

Reply
 
Search this Thread
Old 06-07-2010, 07:04 AM   #1
AshishJogeshwar
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Rep: Reputation: 0
Pipelining data of find command in an array after processing the contents of the data


Hi

I am searching for a file in a specific folder using the following command and storing it in a log file

find . -maxdepth 2 -type f -name "components.xml" -print | while read obj
do
basename `dirname $obj` >> avail_list.log
done


Here i want to do the following
1. Store each entry after processing in an array variable.
2. Use this array variables as arguments to function calls.

Here my primary objective is to store the entries from 'find' command in an array. So it is ok for me if i am not creating the log file.

Regards,
Ashish
 
Old 06-07-2010, 07:26 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374Reputation: 2374
Hi,

Don't double/cross post, it is against the LQ rules.

Continue in this thread (disregard, other thread was closed by a mod.)

Last edited by druuna; 06-07-2010 at 01:15 PM. Reason: Updated to current situation
 
Old 06-07-2010, 12:28 PM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
Well, it looks like it was the other thread that was closed, so we have to continue here.

Anyway, this should be easy enough to do.

Code:
i=0

while read obj; do

     obj="${obj%/*}"
     array[$i]="${obj##*/}"

     echo "${array[$i]}" >> avail_list.log

     let i++

done <<<"$(find . -maxdepth 2 -type f -name "components.xml" -print)"
Assuming bash, I've cleaned things up a little for you.

I've used $(...) instead of `...`.

I replaced basename and dirname with parameter substitution forms. This might cause some problems if there are odd patterns of directory slashes though. You can always simply use array[$i]="$(basename $(dirname $obj))" instead, if necessary, I suppose.

Finally, I've moved the find command to the end using a here string, which is a better position for use in a while loop, and necessary here if you want the variables/array elements to be accessible outside of it.

Note also that gnu find has a -printf option for formatting its output, which could save you a step or two in the above.

By the way, please use [code][/code] tags in the future, to preserve formatting and improve readibility.

Last edited by David the H.; 06-07-2010 at 12:40 PM. Reason: made a minor alteration and added a link
 
Old 06-08-2010, 08:14 AM   #4
AshishJogeshwar
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Hello David the H.

The solution worked well on my Ubuntu machine having dash, but i faced a different problem when i tried to run it on my target having busybox v1.16.1

And i apologise for my novice mistakes which i made with my post. Hopefully my other threads start on a better note ;-)

my script looks like this now
Code:
switch_app()
{
	dir_name=$1
	echo $1
	echo "entered switch_app"
	xml_file_path=/home/$dir_name
	echo $xml_file_path
	xml_file=$xml_file_path/components.xml
echo $xml_file
	rm ../../usr/bin/components.xml
	ln -s $xml_file ../../usr/bin/components.xml
echo "return from switch_app"
	sync
	return	
}


echo "--------------------------------------"
echo "Available apps are"
echo "--------------------------------------"

i=0
while read obj; do

     obj="${obj%/*}"
     array[$i]="${obj##*/}"

     echo "${array[$i]}"

     let i++

done <<<"$(find . -maxdepth 2 -type f -name "components.xml" -print)"

echo "--------------------------------------"
echo Active topas_app is $active
echo "--------------------------------------"
readlink -f '../usr/bin/components.xml' | while read obj
do
f= basename `dirname $obj`
done
echo "--------------------------------------"
echo
echo "${#array[*]}"
echo "--------------------------------------"
echo "Please enter your choice of topas_app"
echo "--------------------------------------"
for element in $(seq 0 $((${#array[@]} - 1)))
do                
echo "press $element for ${array[$element]}"
done

read entered_val
switch_app ${array[$entered_val]}
And the error is the following
Code:
line 32: syntax error: unexpected redirection
However the links you provided were really helpful in getting my concepts about shell scripting in place :-)

Regards,
Ashish
 
Old 06-08-2010, 10:12 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
Well, that's a different question then, and something you should've mentioned. busybox is a very stripped-down toolset, and likely to not have many of the extensions available in your standard desktop utilities. When your script needs to be portable then you have to be very careful to only use features available on all the systems.

I did a bit of experimenting and some searching, and unfortunately it looks like ash simply doesn't support arrays. You'll have to work out some other way to handle the data. The link above gives a basic workaround, but it isn't exactly pretty.

All the other substitution commands I gave do seem to be supported, however.

I'm not sure I understand all of your code anyway. What's this supposed to do, for example?
Code:
readlink -f '../usr/bin/components.xml' | while read obj
do
f= basename `dirname $obj`
done
First of all, the "f" line is broken, as it uses an embedded command without the proper bracketing (assuming you're actually trying to set a variable here, of course). Also, this is really a variation of what we talked about before, so all my previous comments apply here too. It's using the same while-loop-in-a-pipe subshell I mentioned before, meaning that even if you managed to set f correctly, it wouldn't be available anywhere else in the script (not that I see it being used anywhere else in the script anyway), and basename and dirname can be more efficiently handled with parameter substitutions.

But even more to the point, since there's only one input, the loop itself is completely unnecessary. Just set
f=$(readlink -f ../usr/bin/components.xml).

Last edited by David the H.; 06-08-2010 at 10:13 AM.
 
Old 06-10-2010, 02:52 AM   #6
AshishJogeshwar
LQ Newbie
 
Registered: Dec 2009
Posts: 12

Original Poster
Rep: Reputation: 0
Hello David the H.

My script looks for an xml file in a folder which is basically a list of all the applications available.
it also specifies the currently active application and then gives the user a choice to select any one app from the ones available.

I used a work around from arrays by piping the data to a temporary log file and then reading the user input for specifying which application is to be selected.

Code:
find . -maxdepth 2 -type f -name "components.xml" -print |
{
	while read obj;
	do
		obj="${obj%/*}"
		obj="${obj##*/}" 
		i=$((i+1))
		echo  -e "Press \033[1m $i \033[0m for :-  \033[1m $obj \033[0m"
		echo $obj >> $AVL_APPS
	done
echo "Please select a value"
read entered_val
word=$( cat $AVL_APPS | sed ${entered_val}\!d )
if [ -z "$word" ]
then
echo -e "Wrong Entry :-\033[1m $entered_val \033[0mPlease try again"
else
switch_app $( cat $AVL_APPS | sed ${entered_val}\!d )
fi
This made the script work well :-)

But i thank you specially for all the replies and clarifications you gave on this post.

It is not the output which mattered but what i gained in the process.

Regards,
Ashish
 
  


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
Perl .check if data are exist in the array before adding new data ufmale Programming 12 07-14-2010 06:26 AM
Data Processing help required sunils1973 Programming 4 10-02-2007 05:57 AM
Processing data from a 'foreign' database with mysql, or tools to pre-process data. linker3000 Linux - Software 1 08-14-2007 09:36 PM
Data Processing joelhop Linux - General 8 01-01-2006 09:08 PM
Data Processing Server peter72 Linux - Software 1 06-14-2005 12:17 PM


All times are GMT -5. The time now is 03:51 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration