Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say we have something like:

/tmp/tmp.KVKc82GspR
/tmp/tmp.KVKc82GspR/CONTENTS
/tmp/tmp.KVKc82GspR/opt
/tmp/tmp.KVKc82GspR/opt/source
/tmp/tmp.KVKc82GspR/opt/source/sm
/tmp/tmp.KVKc82GspR/opt/source/sm/LVHDoISCSISR.py
/tmp/tmp.KVKc82GspR/opt/source/sm/LVHDoHBASR.py
/tmp/tmp.KVKc82GspR/verify_update

I want to get:

CONTENTS
opt/source/sm/LVHDoISCSISR.py
opt/source/sm/LVHDoHBASR.py
verify_update

I do have some options but I don like them:

  • cd /tmp/tmp.KVKc82GspR; find . -name '*' would add ./ before and worse would change current directory.
  • ls doesn't work well recursively

Note: I would prefer a single line solution, if possible :D

share|improve this question

migrated from stackoverflow.com Oct 5 '12 at 21:59

This question came from our site for professional and enthusiast programmers.

With GNU find:

find /tmp/tmp.KVKc82GspR -mindepth 1 -printf '%P\n'
share|improve this answer

If you're using GNU find, at least, you can do this:

(cd /tmp/tmp.KVKc82GspR; find . -type f -printf '%P\n')

The () causes it to run in a subshell so your cwd isn't affected. -type f matches only regular files, which is possibly better style than -name '*', but has slightly different semantics.

share|improve this answer

Another possibility, similar to the answer by @rici:

(cd /tmp/tmp.KVKc82GspR; find * -type f -print)

That avoids the -printf that might be slightly (but maybe not noticably) less efficient, and which is a non-universal GNU extension - however it fails if you have any files/subdirectories that start with ..

You could also just post-process finds output:

find /tmp/tmp.KVKc82GspR -type f -print | sed -e 's;^/tmp/tmp.KVKc82GspR/;;'
share|improve this answer
shopt -s globstar

startdir="/tmp/tmp.KVKc82GspR"
for file in "${startdir}"/**; do
    echo "${file/${startdir}}"
done

This will find all files in the directory and list them. It is recursive. I believe it will require bash 4 or higher.

If you want to see the files in your CURRENT directory:

shopt -s globstar
# the ls command has a 1 (one) as the first argument
ls -1d **

So this can be a one-liner like so:

shopt -s globstar ; ls 1d **
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .