Sign up ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to search for files with a certain extension and then move all of them up one level in the folder hierarchy.

Basically I have something like


Im trying to move them up like this:


Ideally it would do something like:

-bash-3.2$ find /path/to/ -name '*.txt'

mv /path/to/directories1/test1/test1.txt /path/to/directories1/test1.txt
mv /path/to/directories2/test2/test2.txt /path/to/directories2/test2.txt
mv /path/to/directories3/test3/test3.txt /path/to/directories3/test3.txt

I've been playing with different options and asking around, anyone have any ideas?


So I tried

`find /path/to/parent/dir -type f -exec mv {} .. \

but I get a Permission Denied

share|improve this question
well I tried this find /path/to/dir -type f -exec sh -c 'mv -i "$1" "${1%/*}"' sh {} \; but end up with this sh: bad substituion – ideal2545 Apr 20 '12 at 18:09
Yeah I'm not to sure, just starting to learn scripting in the last week, could elucidate that if you have a second? – ideal2545 Apr 20 '12 at 18:15
I tried an option from what you linked above, but I get a different error assuming a different OS (Solaris 10 in my case). find test -type f -exec mv {} .. \; output mv: cannot rename test/test2/test3/test.jar to ../crap.jar: Permission denied – ideal2545 Apr 20 '12 at 18:20
Ah yes, I see the problem with this. So this will move the files relative to where I execute the command. What I'm actually trying to do is move the file up one level relative to the file. If that makes sense? – ideal2545 Apr 20 '12 at 20:32
Ah, sorry. I read that wrong. The post I linked to will move the files to the parent directory from where you're starting. You want to move the files to their own parent directory. Deleted my comments as they are obsolete. – slhck Apr 20 '12 at 21:10

2 Answers 2

Create a script called, make it executable.


while [ $# -ge 1 ]
   cp "$1" $parentPath;

Info on parameter substitution found here.

Here is another way of doing writing using awk -


while [ $# -ge 1 ]
   echo $1 | awk -F/ '

                sub(/\ /, "\ ", $0);
                system("mv " $0 " " parentPath );

Run as follows -

find /path/to/parent/dir -iname "*.txt" | xargs  /path/to/scripts/
share|improve this answer
Or (untested, beware) find /path/to/parent/dir -iname "*.txt" -exec /path/to/scripts/ '{}' '+' – Eroen Apr 21 '12 at 16:27
You sure this works with files with spaces or globbing characters in their name? – slhck Apr 22 '12 at 21:03
works fine with spaces – bryan Apr 23 '12 at 1:37

If you have GNU find, you could do (modified from your example):

find /path/to -type f -execdir mv {} .. \;

but Solaris uses POSIX find as standard, which lacks this option. Sometimes the GNU tools are available (as e.g. gfind), though.

Also, the -mindepth switch would probably be very useful in this case to only return files at a given minimum directory depth.

Without GNU find, using a script instead:

for i in $(find /path/to -type f); do
    echo mv -- "${i}" "${i%/*/*}"

This will work unless the file names contain newlines. Run it as above first, and remove the echo if it looks OK (also see the -mindepth remark above).

share|improve this answer
while IFS= read -r -d '' file; do and done < <(find /path/to -type f -print0) will typically achieve the same, and it'd be completely safe, rather than for i in $(find…). – slhck Apr 22 '12 at 21:02
OK, I just don't like to introduce Bashisms, but sometimes they do help. If someone wants to do the script like that, be sure to change #!/bin/sh to #!/bin/bash. – Daniel Andersson Apr 23 '12 at 7:52

Your Answer


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.