-4

Need bash script to display files

#!/bin/bash

my_ls() {
  # save current directory then cd to "$1"
  pushd "$1" >/dev/null
  # for each non-hidden (i.e. not starting with .) file/directory...
  for file in * ; do
    # print file/direcotry name if it really exists...
    test -e "$file" && echo "$2$file"
    # if directory, go down and list directory contents too
    test -d "$file" && my_ls "$file" "$2    "
  done
  # restore directory
  popd >/dev/null
}

my_ls

expected output:

file1
file2
info (directory)
    data
    stuff (directory)
        input
    output
    scripts (directory)
    doit
        helper
    testinput
jobs
results (directory)
    bob
    dave
    mary
Rich
  • 8,108
  • 5
  • 46
  • 59

2 Answers2

1

Here is a bash script that does what you ask.

$ cat tree
#!/bin/bash
# tree [DIR]

ls_tree() {
  dir="${1:-.}"
  while read name ; do
    if [[ -n "$name" ]]; then
      if [[ "$name" =~ :$ ]]; then
        dir="${name%:}"
      else
        echo "$dir/${name%*}"
      fi
    fi
  done
}

show_tree() {
  sed -e 's|^./||' | sort | sed -e 's|/$||' -e 's|[^/]*/|    |g'
}


/bin/ls -1RF "${1:-.}" | ls_tree "${1:-.}" | show_tree

Here is a sample output:

$ tree
fun.rb
fun
    data
    filter.awk
    good
    inputtest.sh
    reqs
    test1.awk
input
pairs
    pairs.sh
split-collections
    indir
        col1
        col2
        col3
    outdir
        file1
        file2
        file21
        file22
        file23
        file3
        file31
        file32
        file33
    split-collections.sh
    t1
tree1
aks
  • 2,328
  • 1
  • 16
  • 15
0

This is a basic one-line solution:

find . -type d -printf '%p (directory)\n' -o -print | LC_ALL=C sort | sed 's:[^/]*/:    :g'

This is the same code split over multiple lines for readability:

find . -type d -printf '%p (directory)\n' -o -print |
LC_ALL=C sort |
sed 's:[^/]*/:    :g'

The LC_ALL=C is to prevent sort doing strange things depending on the locale. There are many solutions to problems like this one on the web. Try searching for find sed tree. The first hit is a StackOverflow question: Tree functionality using sed and find command.

Note that this solution will not work on Mac OS because its 'find' is an old one that does not support the '-printf' option.

Community
  • 1
  • 1
pjh
  • 6,388
  • 2
  • 16
  • 17
  • @user4186509, I've tested the one-liner (cut and pasted from the Stackoverflow page) on several systems and seen no obvious problems. What problems are you seeing? Are you getting an error, or is the output not what you expect? – pjh Dec 03 '14 at 16:14
  • @user4186509, I suspect that you've got a cut and paste error. All the quotes in the code are matched. Maybe some characters got lost from the end of the long line. I've added a multi-line version to the answer, so maybe try using that instead. – pjh Dec 08 '14 at 11:03
  • @user4186509, I've modified the answer to say that it does not work on Mac OS. The question has a 'linux' tag, so I assumed that a linux-only solution would be acceptable. It could be modified to work on Mac OS, but getting the ' (directory)' string in the output would be messy. – pjh Dec 09 '14 at 09:20
  • @user4186509, one option for getting rid of the "." line is to put `tail -n +2` in the pipeline immediately after the `find`: `find . ... | tail -n +2 | LC_ALL=C sort | ...`. – pjh Dec 09 '14 at 15:23
  • @user4186509, the output from this might be closer to what you want: `find . -type d -printf '%P (directory)\n' -o -printf '%P\n' | tail -n +2 | LC_ALL=C sort | sed 's:[^/]*/: :g'`. – pjh Dec 10 '14 at 13:36