1

I have files in /home/jjblack/foo/. I want to move all the contents of this directory into /home/jjblack/foo/bar/.

I am unable to copy the contents elsewhere as there is not enough disk space. I am able to

mv /home/jjblack/foo /home/jjblack/xyz
mkdir /home/jjblack/foo
mv /home/jjblack/xyz /home/jjjblack/foo/bar

However is there is a more elegant one-line solution to this?

2 Answers 2

0
cd /home/jjblack/foo
mkdir bar && mv * bar/
2
  • 1
    Note that if the directory contains hidden names, then these would not be moved by the command that you show. There might also be complications if any name starts with a dash.
    – Kusalananda
    Jun 23 at 5:25
  • This will also try to move bar into bar, which will cause mv to complain and exit with a status of 1 (indicating an error). Jun 23 at 9:28
0

The sequence of commands that you show, here with shortened pathnames assuming jjblack is the current user (use ~jjblack in place of ~ otherwise):

mv ~/foo ~/xyz
mkdir ~/foo
mv ~/xyz ~/foo/bar

I would argue that this is rather elegant and that the only thing this lacks is a couple of safety checks to make sure none of the later commands is executed if a previous command fails:

[ ! -e ~/xyz ] &&
mv ~/foo ~/xyz &&
mkdir ~/foo &&
mv ~/xyz ~/foo/bar

or, if you need it on a single line:

[ ! -e ~/xyz ] && mv ~/foo ~/xyz && mkdir ~/foo && mv ~/xyz ~/foo/bar

This is now a single "complete command" (in the shell grammar sense) consisting of an "AND-list" of "simple commands".

This avoids any issue with hidden names, it doesn't expand globbing patterns resulting in a list of potentially millions of names, it does not try to move individual files (slower than moving a single directory), and it does not use any large amount of extra storage. It also successfully moves the meta-data (ownership and permissions etc.) of the original foo directory to the new name bar.

The other way to perform the same operation is by creating the new parent directory first and renaming it at the end. This allows us to get rid of the -e test as mkdir would fail if the ~/xyz name already exists.

mkdir ~/xyz &&
mv ~/foo ~/xyz/bar &&
mv ~/xyz ~/foo

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.