I have some files in different nested directories. All the files are named Analysis.mzXML. I would like to have them all in one place, while changing the name of each one to something different, depending on the directories it was previously saved on.

I know that moving a file and giving it the directory name has been shown earlier in other questions such as this, this and this.

However, they only use the programs to move them one directory out and only change the name based on that one directory. In my case, I would like the files to be renamed using the entire route of nested directories

The files are all saved as follows:


Each Analysis.mzXML is nested in folders of different names. However, dir6 happens to have the same name for all files, and since it no offers valuable information I would like to skip it.

My expectation is that by running some command or script I can get all these files named with their specific route as follows:


I have been just getting started with bash and I am not sure how to come around this issue.


2 Answers 2


Your question, as written, suggests that you want to search the entire filesystem for Analysis.mzXML files, even if they appear in /lib/perl5/5.14/Unicode/Collate/Locale, /proc/sys/net/ipv4/conf/all, /sys/devices/system/cpu/cpu0/cache, /usr/share/doc/cmake/html/_sources, or similarly unlikely / inappropriate places — and that you want to move the files into the root directory, which also seems unlikely / inappropriate.  I assumed that you are working from some other directory.

Run this command:

find . -mindepth 7 -maxdepth 7 -type f -name Analysis.mzXML -exec sh -c 'for arg do echo mv -i -- "$arg" "$(echo "$arg" | sed -e "s|^\./||" -e "s|/dir6/Analysis\.mzXML|.mzXML|" -e "s|/|_|g")"; done' sh {} +

You can leave out the -mindepth 7 -maxdepth 7 if you’re sure that all the Analysis.mzXML files are at the seventh level.  This command finds all Analysis.mzXML files at the seventh level and passes them to a mini-shell script.  That takes each pathname, strips off the ./ at the beginning and the dir6 at the end, along with the Analysis part of the filename, and changes all the remaining / characters to _.  This should produce an output something like this:

mv -i -- ./dir1/dir2/dir3/dir4/dir5/dir6/Analysis.mzXML dir1_dir2_dir3_dir4_dir5.mzXML
mv -i -- ./the/quick/brown/fox/jumps/dir6/Analysis.mzXML the_quick_brown_fox_jumps.mzXML
mv -i -- ./over/the/lazy/dog/foo bar/dir6/Analysis.mzXML over_the_lazy_dog_foo bar.mzXML

If this looks right, run the command again, but delete the first echo (i.e., change echo mv to just mv).


  • This doesn’t verify that the sixth level directory is actually called dir6.  If it finds an Analysis.mzXML file in dir11/dir12/dir13/dir14/dir15/dir16, it will rename that file to dir11_dir12_dir13_dir14_dir15_dir16_Analysis.mzXML rather than dir11_dir12_dir13_dir14_dir15.mzXML.
  • The -i will cause mv to ask for confirmation if it tries to move a file to a name that already exists.
  • The -- should protect you against arguments that begin with -.  This shouldn’t be an issue, since $arg should always begin with ./.
  • If you really want to do this from the filesystem root, that should work.  Just cd / and follow the above instructions.

Afterthought: This might fail if you have a directory named Analysis.mzXML.  So don’t do that.

  • Thank very much you for your thorough explanation of the commands. You are correct; I do indeed intend to search a specific directory, not my entire system. How can I be more clear about this in future questions? I will run this as soon as I can and get back to you in a few hours. Commented Apr 3, 2018 at 13:57

If you're moving only one file with mv, you specify the source filename and then the target filename OR the target directory if you want it to have the same name in a different directory. e.g.

mv /path/to/Analysis.mzXML /new/directory/new-filename.mzXML

or (keeping the same filename in the new directory):

mv /path/to/Analysis.mzXML /new/directory/

If you're moving multiple files, the target MUST be a directory. e.g.

 mv /path/to/*.mzXML /new/directory/

The same is true if you want to copy a file or files, with cp rather than mv.

  • Thank you, I will use the second option then. How can I give it the file derived from the path? The solution includes awk in many cases but it gives it the file name of the directory searched being searched. Since this is nested and I want to include some names and not all, I do not know how to modify it so that each .mzXML file is changed correctly. Commented Mar 15, 2018 at 14:17
  • i have no idea what you mean by "the file derived from the path". BTW, if you want to do very complex renames, then you can use the rename utility (the perl version, not the one in util-linux) - anything you can do in perl that ends up modifying $_ can be used to rename files.
    – cas
    Commented Mar 15, 2018 at 14:24
  • I meant filename. Commented Mar 15, 2018 at 16:34
  • 1
    With all due respect, I’m soooooooo tempted to flag this as “not an answer”.  The question seems to be asking about renaming foo/bar/Analysis.mzXML to foo-bar.  While your post is relevant, I don’t see how it comes close to answering the question.  P.S. Why do you say *.mzXML when the question says that all the files are named Analysis.mzXML? Commented Mar 16, 2018 at 6:47
  • 1. The OP's question is barely coherent and extremely difficult to make sense of. It should probably be on hold as Unclear. The best I could figure out was that he didn't know the conventions for specifying sources and targets for mv. He seemed to appreciate having that spelled out in my answer. 2. Why *.mzXML? There's a conditional: "if you're moving multiple files". If someone doesn't know how to mv a single file, it's a safe bet that they could use some help with mv-ing multiple files too. 3. Also, even after 5+ readings, I never noticed that he said all filenames are the same.
    – cas
    Commented Mar 16, 2018 at 7:11

You must log in to answer this question.

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