views:

52

answers:

4

Quick Background:

$ ls src
file1  file2  dir1  dir2  dir3

Script:

#!/bin/bash

for i in src/* ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done

Output:

src/dir1
src/dir2
src/dir3

However, I want it to read:

dir1
dir2
dir3

Now I realize I could sed/awk the output to remove "src/" however I am curious to know if there is a better way of going about this. Perhaps using a find + while-loop instead.

+1  A: 

Do this instead for the echo line:

 echo $(basename "$i")
Gonzalo
Nope, that will output:src/src/src/
BassKozz
Use basename instead of dirname
Gonzalo
I see you've updated your post to read *basename* instead of *dirname*ding,ding,ding CORRECT !!! :DThanks, I will accept your answer
BassKozz
Learnt this nugget just 2 days ago from an O'Rielly book. Could have saved me hours of sed tomfoolery if I'd know it years ago.
Synesso
+2  A: 

Use basename as:

if [ -d "$i" ]; then
    basename "$i"
fi
codaddict
+2  A: 

No need for forking an external process:

echo "${i##*/}"

It uses the “remove the longest matching prefix” parameter expansion. The */ is the pattern, so it will delete everything from the beginning of the string up to and including the last slash. If there is no slash in the value of $i, then it is the same as "$i".

This particular parameter expansion is specified in POSIX and is part of the legacy of the original Bourne shell. It is supported in all Bourne-like shells (sh, ash, dash, ksh, bash, zsh, etc.). Many of the feature-rich shells (e.g. ksh, bash, and zsh) have other expansions that can handle even more without involving external processes.

Chris Johnsen
+1  A: 

If you do a cd at the start of the script, it should be reverted when the script exits.

#!/bin/bash

cd src
for i in * ; do
  if [ -d "$i" ]; then
    echo "$i"
  fi
done
Mark Ransom
it should… but if you use the `.` or `source` command to invoke the script, it won't. Rather use `pushd` and `popd`.
Benoit