Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

URGENT !!!     Associative arrays in ksh scripting

Posted on 2006-06-12
20
2,297 Views
Last Modified: 2013-12-26
How do I create and initialize an associative array. I tried :

typeset -AE usage (where usage is the name of te array), but it shows me    typeset: bad option(s)  

Urgent reply needed.
Thanks !
0
Comment
Question by:Shweta_Singh
  • 10
  • 4
  • 4
  • +1
20 Comments
 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 16888179


For KSH shell use:

set -A usage ...etc...(values separated by space)

For Linux use:

usage=( ...etc...values separated by space)

0
 

Author Comment

by:Shweta_Singh
ID: 16888388
How do I create and initialize an associative array. I tried :

typeset -AE usage (where usage is the name of te array), but it shows me    typeset: bad option(s)  

Also, I can assign values only one by one, through a loop and not seperated by spaces

Urgent reply needed.
Thanks !
0
 
LVL 38

Expert Comment

by:yuzh
ID: 16891380
Please have a look at the example in:

http:Q_20771322.html#9580607

and http:Q_20894122.html

The Ksh array can have a MAX 512 elements. [0-511].
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 

Author Comment

by:Shweta_Singh
ID: 16894259
I want to write a ksh (korn shell) script to show disk usage per user.

Description:  
The script should take in a single command-line argument--the directory name, and display the usage in MB per user.  Please comment your code for readability.  I tried to use the Unix ‘du’ command or you can write your own method to accomplish this task.


Thnaks !
0
 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 16894407

This post looks like homework, please reread out member agreement:
http://www.experts-exchange.com/help.jsp#hi130


0
 

Author Comment

by:Shweta_Singh
ID: 16894788
I want to write a ksh (korn shell) script to show disk usage per user. The script should take in a single command-line argument--the directory name, and display the usage in MB per user.

I have managed to get the files listings in the directory and then check who the owner of the file was. But, I am unable to associate the space taken up by the file to it's particular owner. If I could find a way to do that, I would simply add the space of the files of similar owners. Please let me know, if I'm thinking wrong and please suggest on how to proceed further. Associateive arrays might help but I dont know that they exist in ksh or not. If yes, then how do I create one and set values to it ??

NOTE: Associative arrays are different than the normal arrays. Please dont give me a way to declare a simple array. I tried typeset to create an associative array, but it dosen't work !!
0
 
LVL 3

Expert Comment

by:root_start
ID: 16905160
Hi Shweta_Singh,

If I undestood your problem, check the following:
====================================================================================================
#!/bin/bash
####################################################################################################

####################################################################################################
# Return Users
####################################################################################################
getUsersInPath ()
{
      ls -l "${1}" | sed 1d | awk '{print $3}' | sort | uniq
}
####################################################################################################

##################################################################################################### Disk Usage by user
####################################################################################################getDiskUsage ()
{
      user="${1}"
      checkPath="${2}"
      ls -l "${checkPath}" | sed 1d | grep ${user} | grep -v grep | awk 'BEGIN{sum=0} {sum+=$5} END{print sum}'
}
####################################################################################################

##################################################################################################### Print Disk Usage
####################################################################################################
printDU ()
{
      checkPath="${1}"
      for user in `getUsersInPath "${checkPath}"`
      do
            echo "User: [${user}] - Disc usage: [`getDiskUsage ${user} ${checkPath}`] - Path: [${checkPath}]."
      done      
}
####################################################################################################

printDU "."

====================================================================================================

It is really simple, but I think it does what you were expecting.

If you have questions, post here.

I hope it helps. =0)
0
 

Author Comment

by:Shweta_Singh
ID: 16905601
Hey root_start:

Thanks for that response. If you could please explain me what parameters are to be passed in.

Thanks again
Shweta
0
 
LVL 3

Expert Comment

by:root_start
ID: 16905732
Hi Shweta,

You only need to call the function "printDU" passing the "path".
e.g.

printDU "/etc"

Let me know if you have doubts.
0
 
LVL 3

Expert Comment

by:root_start
ID: 16906030
Ops... a correction to the script:
====================================================================================================
#!/bin/bash
####################################################################################################

##################################################################################################### Return Users
####################################################################################################getUsersInPath ()
{
        ls -l "${1}" | sed 1d | awk '{print $3}' | sort | uniq
}
####################################################################################################

##################################################################################################### Disk Usage by user
####################################################################################################getDiskUsage ()
{
        user="${1}"
        checkPath="${2}"
        ls -l "${checkPath}" | sed 1d | grep ${user} | grep -v grep | awk 'BEGIN{sum=0} {sum+=$5} END{print sum}'
}
####################################################################################################

####################################################################################################
# Print Disk Usage
####################################################################################################
printDU ()
{
        checkPath="${1}"
        for user in `getUsersInPath "${checkPath}"`
        do
                echo "User: [${user}] - Disc usage: [`getDiskUsage ${user} "${checkPath}"`] - Path: [${checkPath}]."
        done
}
####################################################################################################

printDU "."
====================================================================================================

I add a double quotes to when I call, to the variable ${checkPath}.
getDiskUsage ${user} "${checkPath}"

Otherwise if the script faces a path with a space on it, the script would fail.
0
 

Author Comment

by:Shweta_Singh
ID: 16906117
The disk usage we would get by this method would be incorrect . The disk usage that this shows is ll | awk '{print $5}'  where as what I want is du -sk (path)

The total disk usage .

0
 
LVL 29

Accepted Solution

by:
MikeOM_DBA earned 500 total points
ID: 16907656

Instead of using 'du' try something more simple like:

#!/bin/ksh
find $1 -ls|\
awk '{o[$5]+=$7;}
END {for (i in o) print i " uses " o[i] " bytes.";}'

PS: Parameter 1 ($1) is the top direcctory name from which you want to sum the disk usage.


0
 

Author Comment

by:Shweta_Singh
ID: 16912047
find $1 -ls wouldn't work on std unix.
0
 
LVL 38

Expert Comment

by:yuzh
ID: 16917039
>>find $1 -ls wouldn't work on std unix.

$1 is the first commandline arg, in commandling you type in:

/path-to/scipt /home

/home is $1

Please have a look at the following page to learn some basic scripting:

http://steve-parker.org/sh/sh.shtml
http://www.shelldorado.com/links/#tutorials
http://www.codebox.8m.com/shellscripting.htm

0
 

Author Comment

by:Shweta_Singh
ID: 16922709
i knew that already .

I meant find (pathname) -ls wpn't work on std unix

Thanks
0
 
LVL 29

Expert Comment

by:MikeOM_DBA
ID: 16936360

>>I meant find (pathname) -ls wpn't work on std unix

Yes it will:

$ find /oracle/local/tmp -ls
979441    4 drwxrwxr-x   2 oraweb   dba          4096 Jul 19  2005 /oracle/local/tmp
979442 1528 -rw-r--r--   1 oraweb   dba       1556681 Jul 19  2005 /oracle/local/tmp/Agenda.ear
979443  716 -rw-r--r--   1 oraweb   dba        729088 Jul 19  2005 /oracle/local/tmp/cjss_report77.rdf
$
0
 

Author Comment

by:Shweta_Singh
ID: 16943254
Okay,
This is where I have reached uptil yet .

All you need to know is that I made an array and that I need to access it's variables which i'm unable to .
Pls help.


#!/usr/bin/ksh
#CREATE AN ARRAY TO STORE OWNERS TO COMPARE
set -A owners `ls -lR "${1}" 2>/dev/null | sed 1d | awk '{print $3}' | sort | uniq`

#LOOP OVER THE ARRAY TO GET THE OWNERS ONE BY ONE TO COMPARE
i=0
while [ $i -lt ${#owners[*]} ]
do
        `ls -lsR "${1}" | awk '/$owners[$i]/ {disk_usage += $6} END {print $owners[$i], " : ", 1*disk_usage, " MB"}'`

        ((i=i+1))
done
0
 

Author Comment

by:Shweta_Singh
ID: 16943266
$ find /appl -ls
find: bad option -ls
0
 
LVL 3

Expert Comment

by:root_start
ID: 16946972
Hi Shweta_Singh,

I changed one line in the script I posted above to use the "du -sk" command.
Check below:
===================================================================================================
ls -l "${checkPath}" | sed 1d | grep "${user}" | grep -v grep | awk '{nfields=NF; path="'${checkPath}'"; print path"/"$nfields}' | xargs du -sk 2>> /dev/null | awk 'BEGIN{sum=0} {sum+=$1} END{print sum}'
===================================================================================================

Just change the following line in the script:
     ls -l "${checkPath}" | sed 1d | grep ${user} | grep -v grep | awk 'BEGIN{sum=0} {sum+=$5} END{print sum}'
by the one I posted above.

I hope it helps. =0)
0
 

Author Comment

by:Shweta_Singh
ID: 16953486
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question