Help with Shell Script displaying Directories


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Help with Shell Script displaying Directories
# 1  
Old 04-20-2009
Help with Shell Script displaying Directories

I am new to shell programming and have an assignment question which requires me to list the contents of the present working directory in 4 column format and highlight any subdirectories. It then requires me to develop the shell script to accept a directory name as a positional parameter (if no parameter use the present working directory); then adapt is to accept more than one directory as positional parameters; and finally adapt it to display the name of the sub directory and ask whether to: descend and list the contents, list the contents without changing the present working directory, or ignore the directory. (it was suggested that a recursive call would be handy)

I am struggling to write a shell script which performs this task. I found the following script in a forum which i think was written for old version shell (SH). I have tried to reuse this shell and adapt it to the BASH shell. If anyone is able to help me either adapt the below code or have any suggestions on how i can go about this question. Please help. Major thanks in anticipation.

Code:
#!/bin/sh

if [ -n "$1" ]
then
 WORKDIR=$1
else
 WORKDIR=`pwd`
fi

WORKDIR=`echo $WORKDIR | awk \
'{
  if (substr($0,length($0),1)=="/")
  {
   print substr($0,1,length($0)-1)
  } else {
   print $0
  }
 }'`

echo $WORKDIR

for DIR in `ls -l $WORKDIR | grep "^d" | awk '{ print $NF }'`
do
 echo "Found directory $DIR, Decend, List, Ignore (D,L,I) ?"
 read DLI
 DLI=`echo $DLI | tr "dli" "DLI"`
 case $DLI in
  "D" ) $0 $WORKDIR/$DIR;;
  "L" ) ls -l $WORKDIR/$DIR | grep -v "^d" | awk -v COUNTER=0 \
'{
  printf "%s ",$NF
  COUNTER++
  if (COUNTER>=5)
  {
   printf "\n"
   COUNTER=0
  }
 }' | column -t;;
  "I" ) echo "Ignored directory $DIR";;
 esac
done
 
ls -l $WORKDIR | grep -v "^d" | awk -v COUNTER=0 \
'{
  printf "%s ",$NF
  COUNTER++
  if (COUNTER>=5)
  {
   printf "\n"
   COUNTER=0
  }
 }' | column -t

regards Clinton

Last edited by Franklin52; 04-21-2009 at 04:54 AM.. Reason: adding code tags
# 2  
Old 04-20-2009
Quote:
Originally Posted by cjnd1988
I am new to shell programming and have an assignment question which requires me to list the contents of the present working directory in 4 column format and highlight any subdirectories.

Homework assignments are not permitted here, but maybe this will get you started:

Code:
unset files
n=0
for file in *
do
  [ -d "$file" ] &&
     files[${#files[@]}]=$file/ ||
     files[${#files[@]}]=$file
done
w=$(( $COLUMNS / 4 - 1 ))
printf "%-$w.${w}s %-$w.${w}s %-$w.${w}s %-$w.${w}s\n" "${files[@]}"

Quote:

It then requires me to develop the shell script to accept a directory name as a positional parameter (if no parameter use the present working directory); then adapt is to accept more than one directory as positional parameters; and finally adapt it to display the name of the sub directory and ask whether to: descend and list the contents, list the contents without changing the present working directory, or ignore the directory. (it was suggested that a recursive call would be handy)

I am struggling to write a shell script which performs this task. I found the following script in a forum which i think was written for old version shell (SH). I have tried to reuse this shell and adapt it to the BASH shell.

With very few exceptions, scripts written for sh will run without modification in bash.
Quote:
If anyone is able to help me either adapt the below code or have any suggestions on how i can go about this question.

Please put code inside [code] tags.
Quote:
Code:
#!/bin/sh

if [ -n "$1" ]
then
 WORKDIR=$1
else
 WORKDIR=`pwd`
fi

WORKDIR=`echo $WORKDIR | awk \
'{
  if (substr($0,length($0),1)=="/")
  {
   print substr($0,1,length($0)-1)
  } else {
   print $0
  }
 }'`

echo $WORKDIR

for DIR in `ls -l $WORKDIR | grep "^d" | awk '{ print $NF }'`
do
 echo "Found directory $DIR, Decend, List, Ignore (D,L,I) ?"
 read DLI
 DLI=`echo $DLI | tr "dli" "DLI"`
 case $DLI in
  "D" ) $0 $WORKDIR/$DIR;;
  "L" ) ls -l $WORKDIR/$DIR | grep -v "^d" | awk -v COUNTER=0 \
'{
  printf "%s ",$NF
  COUNTER++
  if (COUNTER>=5)
  {
   printf "\n"
   COUNTER=0
  }
 }' | column -t;;
  "I" ) echo "Ignored directory $DIR";;
 esac
done

ls -l $WORKDIR | grep -v "^d" | awk -v COUNTER=0 \
'{
  printf "%s ",$NF
  COUNTER++
  if (COUNTER>=5)
  {
   printf "\n"
   COUNTER=0
  }
 }' | column -t

# 3  
Old 04-21-2009
Thank - you very much for your reply and thanks for the starting point. Could you please just briefly explain what the following lines are doing just so i fully understand.

Code:
for file in *
do
  [ -d "$file" ] &&
     files[${#files[@]}]=$file/ ||
     files[${#files[@]}]=$file
done

# 4  
Old 04-21-2009
how to test if a directory or not?

I have got the following segment of code. It is going through each file/directory in the present working directory and asking whether it should descend into the directory. If deciding to descend it recalls the shell script with the new directory as a parameter. This is probably not the most efficient way of doing/writing this code but it seems to work. What i want to do is though, i want to only execute this code if it is a directory not if its a file. How do i test for if its a directory before descending into the code.
Code:
echo "The present working directory is: $WORKDIR "
cd $WORKDIR

for directory in *
do
    (I am thinking the test will go in here to test the value of $directory)
    echo "Found directory $directory; do you want to Descend, List or Ignore:"
    read answer
    case $answer in
    "D") WORKDIR=$WORKDIR/$directory
           echo $WORKDIR
           exec ./tryc $WORKDIR;;
     "L") (this will call a function to list the contents of the directory);;
     "I") echo "The directory was ignored" ;;
     esac
done

[/QUOTE]
# 5  
Old 04-21-2009

Use test -d.

Code:
if [ -d "$directory" }
then
   echo "$directory is a directory"
else
   echo "$directory is not a directory"
fi

Or you can bypass the test altogether; this will only list directories:

Code:
for directory in */

# 6  
Old 04-22-2009
I have got my coding to the following. So far the code calls a function which is used to go through the contents of the directory and ask whether to descend (which recalls the function with the new directory), list the contents of the directory (which calls the another function designed to list the contents).
My problem is with the listing of the contents. Displaying the contents of the first directory is fine. When i go to display the contents of the second directory, what is displayed is the contents of the first directory with the contents of the second directory appended to the end. I do not want this to happen, i only want it to display the contents of the current directory only.
What have i done wrong to make it do this.

Also at present my shell is only set up to accept one parameter, how would i go about setting it up to accept multiple parameters. Use a while loop maybe around the calling functions incrementing the parameter number??
Code:
#!/bin/bash



displaydir()

{
	n=0

	local alist=$( ls $1 )

	for file in $alist

	do

	[ -d "$file" ] &&

		files[${#files[@]}]=$file/ ||

		files[${#files[@]}]=$file

	done

	w=10
 #$(($COLUMNS/4-1))

	printf "%-$w.${w}s %-$w.${w}s %-$w.${w}s %-$w.${w}s\n" "${files[@]}"
	
}


#unset files

#unset answer



descenddir()

{
	local BASEDIR=$1

	local LOCALDIR="$PWD"


	echo "The present working directory is: $BASEDIR "

	cd $BASEDIR

	echo "Do you want to display the contents of this directory?"

	read answer

	case $answer in

	"Y") displaydir "$BASEDIR";;

	"N") ;;

	esac



	local dirlist=$( ls )

	for directory in $dirlist

	do

		if [ -d $directory ]
 
		then {

			echo "Found directory $directory; do you want to Descend, List or Ignore (D,L, I): "

			read answer

			case $answer in

			"D") descenddir "$BASEDIR/$directory/";;

			"L") displaydir "$BASEDIR/$directory/";;

			"I") echo "The directory was ignored" ;;

			esac
 
		}

		fi

	done

	cd $LOCALDIR

}



if [ $1 ]
 
   then descenddir $1
 
   else descenddir "$PWD"

fi

# 7  
Old 04-22-2009
Quote:
Originally Posted by cjnd1988
I have got my coding to the following. So far the code calls a function which is used to go through the contents of the directory and ask whether to descend (which recalls the function with the new directory), list the contents of the directory (which calls the another function designed to list the contents).
My problem is with the listing of the contents. Displaying the contents of the first directory is fine. When i go to display the contents of the second directory, what is displayed is the contents of the first directory with the contents of the second directory appended to the end. I do not want this to happen, i only want it to display the contents of the current directory only.

Which line is giving you the problem?
Quote:
What have i done wrong to make it do this.

Also at present my shell is only set up to accept one parameter, how would i go about setting it up to accept multiple parameters. Use a while loop maybe around the calling functions incrementing the parameter number??

Code:
if [ $# -gt 0 ]
then
  for dir
  do
    descenddir "$dir"
  done
else
  descenddir "$PWD"
fi

Quote:
Code:
#!/bin/bash

displaydir()
{
   n=0
   local alist=$( ls $1 )
   for file in $alist


That will break if any filenames contain spaces. Use:

Code:
for file in "$1"/*

Or cd into the directory:

Code:
cd "$1"
for file in *

Quote:
Code:
   do
     [ -d "$file" ] &&
      files[${#files[@]}]=$file/ ||
      files[${#files[@]}]=$file
   done

   w=10  #$(($COLUMNS/4-1))

   printf "%-$w.${w}s %-$w.${w}s %-$w.${w}s %-$w.${w}s\n" "${files[@]}"
}

#unset files
#unset answer

descenddir()
{


It would make things simpler if you execute descenddir() in a subshell:

Code:
descenddir()
(

)

Then you don't need to worry about returning to a previous directory.
Quote:
Code:
   local BASEDIR=$1
   local LOCALDIR="$PWD"

   echo "The present working directory is: $BASEDIR "

   cd $BASEDIR


That will break if $BASEDIR contains spaces. Quote the variable and check that it succeeded:

Code:
cd "$BASEDIR" || return 1

Quote:
Code:
   echo "Do you want to display the contents of this directory?"
   read answer
   case $answer in
     "Y") displaydir "$BASEDIR";;
     "N") ;;
   esac

Code:
   case $answer in
     [yY]) displaydir "$BASEDIR";;
   esac

Quote:
Code:
   local dirlist=$( ls )

   for directory in $dirlist


That will break if any filenames contain spaces. Use:

Code:
for file in *

Quote:
Code:
   do
      if [ -d $directory ]
      then {


There's no need for the braces.
Quote:
Code:
    echo "Found directory $directory;
  do you want to Descend, List or Ignore (D,L, I): "
    read answer

    case $answer in
      "D") descenddir "$BASEDIR/$directory/";;
      "L") displaydir "$BASEDIR/$directory/";;
      "I") echo "The directory was ignored" ;;
    esac

Code:
   case $answer in
      [dD]) descenddir "$BASEDIR/$directory/";;
      [lL]) displaydir "$BASEDIR/$directory/";;
      [Ii]) echo "The directory was ignored" ;;
   esac

Quote:
Code:
 
      }
      fi

   done

   cd $LOCALDIR


That will break if $LOCALDIR contains spaces. Quote the variable and check that it succeeded:

Code:
cd "$LOCALDIR" || return 1

Quote:
Code:
}

if [ $1 ]
   then descenddir $1


That will break if $1 contains spaces. Quote the variable:

Code:
   then descenddir "$1"

Quote:
Code:
   else descenddir "$PWD"
fi

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Displaying Column header in shell script

Hi, I need to display specific columns using select statement and spooled to a file and sending it as e-mail. But i am not seeing column header in my output even i use SET HEADING ON.//PREDEFINED LOGIN DETAILS ${ORACLE_HOME}/bin/sqlplus -s ${DB_LOGIN}/${DB_PASSWD} <<EOF SET FEEDBACK OFF SET... (1 Reply)
Discussion started by: pvelmuru
1 Replies

2. UNIX for Dummies Questions & Answers

Shell Script for displaying the line till the target word

" Script for display sentences with special character" Hi, Could any one share a command how to display a line until my target word. For ex: My file has the content as: select * from db_wrk where col1 < col2 insert into table_name values('1','2','tst','wrk','dev','prod') My target... (10 Replies)
Discussion started by: Kalaiselvi66
10 Replies

3. Shell Programming and Scripting

creating multiple sub-/directories using a shell script

0 Hi, I am looking for a way of creating multiple directories using the mkdir -p command in a shell script. I'm working with an Ubuntu machine and try to do something like that: #!/bin/sh ... (3 Replies)
Discussion started by: frymor
3 Replies

4. Shell Programming and Scripting

Shell script to modify file in several directories

Hi, I want a script shell to automate modifying httpd.conf file for several instances of apache, save httpd.file before changing it, after modifying it and then restart apache. - Replace ServerRoot "xxxx" by ServerRoot "yyyy" of all directories : "... (4 Replies)
Discussion started by: bras39
4 Replies

5. Shell Programming and Scripting

how to convert a shell script to a php script for displaying next word after pattern match

I have a shell script which I made with the help of this forum #!/bin/sh RuleNum=$1 cat bw_rules | sed 's/^.*-x //' | awk -v var=$RuleNum '$1==var {for(i=1;i<=NF;i++) {if($i=="-bwout") print $(i+3),$(i+1)}}' Basically I have a pages after pages of bandwidth rules and the script gives... (0 Replies)
Discussion started by: sb245
0 Replies

6. Shell Programming and Scripting

renaming directories with shell script

Hi All after looking around the website and various other resources I become stuck. I'm trying to rename directories from Firstname Initial Lastname to lastname,_firstname_initial so far ive got for f in {./} do rename -n 'y/A-Z/a-z/' * rename -n 's/\ /_/g' * ... (2 Replies)
Discussion started by: harlequin
2 Replies

7. Shell Programming and Scripting

Displaying uppercase in shell script

Hi, The user value y/n should get display in upper case printf "$FBOLD\nDo you want to continue?: $FREG" Do you want to continue?: y Though user enters in smaller case y, but it should get display in uppercase Y How it can be done ? With Regards (2 Replies)
Discussion started by: milink
2 Replies

8. UNIX for Dummies Questions & Answers

Help displaying contents of Directories - Urgent

I am new to shell programming and have an assignment question which requires me to list the contents of the present working directory in 4 column format and highlight any subdirectories. It then requires me to develop the shell script to accept a directory name as a positional parameter (if no... (1 Reply)
Discussion started by: cjnd1988
1 Replies

9. Shell Programming and Scripting

shell script to delete directories...

*Just realized that i posted this in the wrong forum. should have been in Shell, though it is on AIX... Hi. I'm trying to write a script that will delete all directories found, that are not named as a "number" (year)... here is what i mean, let's say i have within /data/exports the... (8 Replies)
Discussion started by: Stephan
8 Replies

10. Shell Programming and Scripting

shell script to delete directories...

Hi. I'm trying to write a script that will delete all directories found, that are not named as a "number" (year)... here is what i mean, let's say i have within /data/exports the following directories: /data/exports/2000 /data/exports/2001 /data/exports/2002 /data/exports/daily/2000... (5 Replies)
Discussion started by: Stephan
5 Replies
Login or Register to Ask a Question