Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

if there are several subdirectories in the current working directory, i would like to move only specific filetypes or possibly all the contents of those directories, to the working directory. and then; "rmdir *" those empty directories or "rm -r" those directories (if not empty)

Shouldn't this be done with the "find" utility then pipe | the output to "mv ." (move find results to working directory)? If so what are the find options that i need to pass for example, or What sort of commands should be used to rm or mv files in the subdirectories, and maybe remove the directories afterward?

Is this method safe for moving duplicate filenames in the same directory? or would the files be overwritten, if there are many index.htmls for instance

This should be a basic task in unix, mv or rm specified filetypes from several subdirectories

share|improve this question

2 Answers 2

The following moves all HTML files out of foo, and removes empty directories:

$ find foo -name '*.html' -type f -exec mv -nv "{}" '.' \;
foo/bar/1.html -> ./1.html
./1.html not overwritten
foo/baz/qux/3.html -> ./3.html
foo/baz/qux/5.html -> ./5.html
$ find foo -depth -type d -delete

What's left is HTML files with conflicting file names, files that aren't HTML files, and non-empty folders.

To automatically rename files to prevent duplicate file names, you can use mktemp. The syntax is different between operating systems, and the below works on OS X and presumably the BSDs:

find foo -name '*.html' -type f -exec bash -c 'mv -v "$0" "./$( mktemp "$( basename "$0" ).XXX" )"' '{}' \;
foo/bar/1.html -> ./1.html.yNr
foo/baz/1.html -> ./1.html.RUu
foo/baz/qux/3.html -> ./3.html.rzu
foo/baz/qux/5.html -> ./5.html.JyW

For every HTML file it finds, it launches bash and has it execute the command after -c, which is really just an mv with a dynamically created (using mktemp) destination file name in the current directory.

To make sure it will work as intended, you can echo the mv command first as a preview:

find foo -name '*.html' -type f -exec bash -c 'echo mv -v "$0" "./$( mktemp "$( basename "$0" ).XXX" )"' '{}' \;
mv -v foo/bar/1.html ./1.html.VNf
mv -v foo/baz/1.html ./1.html.pCW
mv -v foo/baz/qux/3.html ./3.html.ADN
mv -v foo/baz/qux/5.html ./5.html.K3w

As you can see, every invocation results in a different suffix thanks to mktemp in the bash script (you cannot just include that part in a regular -exec mv as it'd get evaluated once for the find call, and then use the same suffix for all moved).

Depending on the number of files involved, you might need a larger random suffix than just .XXX.

share|improve this answer

You can do it in one go with a command like:\

find . -name '*.goaway' -exec mv '{}' destination \;

but a safer way may be to to start by just seeing what the find command digs up for you, possibly piping it to a file which you can use for doing the acutal operations.

And yes, if you move all your index.html to the same directory they will clobber each other and you'll only have the last one moved left after.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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