I wrote a simple script to delete useless files from a directory using the find command.

Now I'm wondering if I can add lines to the script to flatten directories, but not completely flattened.

e.g., If I have a big directory named cleantarget:

  • cleantarget
    • Folder A
      • Folder A1
      • Folder A2
    • Folder B
      • Folder B1
        • Folder B11

I want the end result to be:

  • cleantarget
    • Folder A
    • Folder B

I do NOT want the result to be:

  • cleantarget
    • all my files

There are 16000 files in this directory, so it'd be nice to do this with a script, so I can run it occasionally when the directory gets messed up again.

How do I do this?

EDIT: In essence, this means: I want a script, that will separately flatten each sub-directory within a given target directory. i.e., flatten Folder A, flatten Folder B, and flatten Folder C, and so on until all directories within cleanfolder are flattened.

  • 1
    What determines if a file should be deleted? – jesse_b Jun 22 '19 at 16:48
  • 1
    Do you mean flatten all of the directories under 'Folder A' and 'Folder B'. As in move all of the files from the subdirectories in A and B to A and B and then delete the subdirectories in A and B? – Giraffer Jun 22 '19 at 16:56
  • 2
    Did you check to see whether this had been asked before? – Kusalananda Jun 22 '19 at 16:56
  • 2
    So do you want to flatten directory A, and flatten directory B etc.? – ctrl-alt-delor Jun 22 '19 at 16:56
  • 1
    @johnnywatts So, take any of those solutions and apply them to to each folder individually? Doesn't sound more complicated than adding a for-loop around a piece of code. – Kusalananda Jun 23 '19 at 6:51

These lines should work:

find "/path/to/cleantarget" -maxdepth 1 -mindepth 1 -type d | while read line; do
    find "${line}" -mindepth 2 -type f -exec mv -t "${line}" -i '{}' +
    rm -r "${line}"/*/

This will flatten Folder A and Folder B, asking if you want to overwrite duplicates, and remove the folders afterwards.

Source: https://unix.stackexchange.com/a/52816/284212

| improve this answer | |
  • Hello, I don't think that will work. That only scans two folders and flattens them. It doesn't proceed with other folders. – johnnywatts Jun 22 '19 at 23:43
  • @johnnywatts Sorry, I didn't see your update. I only thought there were two folders. – Giraffer Jun 23 '19 at 0:07
  • It should work now. – Giraffer Jun 23 '19 at 0:19
  • My apologies, but it didn't work. I get the error "find: paths must precede expression: 'rm'" – johnnywatts Jun 23 '19 at 0:32
  • 1
    I'd recommend replacing the first find ... | while read loop with a simple for line in "/path/to/cleantarget"/*/; do. One possible downside: it won't flatten invisible subdirectories (unless you set shopt -s dotglob first). – Gordon Davisson Jun 23 '19 at 2:08

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.