I can do this in Windows CMD scripting but now I am getting into Debian via Raspberry Pi.

What I'd like to do is...

(In current folder)

  • For each subfolder...
    • Create a file called original_filenames.txt
    • Echo the name of the folder into this original_filenames.txt
    • List all files (including any subfolders) to original_filenames.txt
  • 1
    What are you having an issue doing? Please include the script you are attempting to use in your question and any errors you are encountering. – kemotep May 30 '18 at 18:28
  • Do you want to descend into subfolders and list those files? – glenn jackman May 30 '18 at 18:57
  • Yes I want to recurse through subfolders. I think I've got something working now, I was getting an error until I added quotes to deal with spaces in folder names:#!/bin/bash; for dir in */ ; do ; tree -s "$dir">"$dir/original_filenames.txt"; done – Murgatroyd May 30 '18 at 19:24
  • That's a good lesson. You'll want to read Security implications of forgetting to quote a variable in bash/POSIX shells – glenn jackman May 30 '18 at 19:27

Using a shell loop:

for dir in */; do
    { printf '%s\n' "$dir"
      ( cd "$dir" && find . )
    } >"$dir/original_filenames.txt"

This iterates over all subdirectories in the current directory. The body of the loop outputs the name of the directory, and then a list of all files and directories, recursively, in that directory. This output goes to the original_filenames.txt file in the directory.


for dir in */; do
    find "$dir" >"$dir/original_filenames.txt"

This gives slightly different output in that the pathnames that are written to the file all start with the name of the subfolder.

If you're uninterested in directory names and just want pathnames of the regular files, use find with -type f after the directory name.

Note that if you're planning on using the generate output files for anything, then this will fail (or at least be very problematic) if any of the found pathnames contain newlines (which is entirely possible on a Unix system).

| improve this answer | |

You could do this with the find command and the exec option - something like this:

find . -type d \( ! -name . \) -exec bash -c '
    dirname=$(basename "{}") && 
    cd "{}" && 
    echo "{}" > original_filenames.txt && 
    ls | grep -Fv original_filenames.txt >> original_filenames.txt
' \;

Here's a StackOverflow post you might find useful:

| improve this answer | |
  • 1
    For readability, you can have newlines in a single quoted string, and && at the end of a line does not require a line continuation. – glenn jackman May 30 '18 at 19:02
  • 1
    Instead of putting {} in the middle of the shell script, you may want to pass it as an argument and use "$1" inside the shell script, to avoid issues with strange filenames. Also, I can't see what dirname is used for here, and you don't need \( \) around ! -name .. – ilkkachu May 30 '18 at 19:15
  • @ilkkachu Thanks for the comment. The unused dirname was a typo/mistake on my part. I'm now using it to add just the filename to the output file. The ! -name . was to ignore the current directory (i.e. to only apply the commands to proper subdirectories) - I removed it. – igal May 30 '18 at 19:21
  • @glennjackman Thanks for the comment. I've update my post as you suggested. – igal May 30 '18 at 19:22
  • 1
    @igal, I added a version I think is readable. If you don't like, please edit it out. – glenn jackman May 30 '18 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.