1

Happy New Year. I have a solution to this, but I can't make it work unless I am in the directory I want to copy.

At the end of 2018, I want to copy the directory structure only of various folders named 2018/ into 2019/.

cd 2018/
find . -type d -exec mkdir -p ../2019/{} \;

And this works. How do I do it from the base directory?

find 2018 -type d -exec basename {} \;

gives me the folder names, but

find 2018 -type d -exec mkdir 2019/`basename {}` \;

still copies the 2018 folder into the 2019 folder, and you loose the directory tree.

I can't find a simple answer after multiple searches. Any ideas?

Edit Thanks for all the help and suggestions. This one ultimately worked best for me:

find 2018/* -type d | sed 's/^2018//g' | xargs -I {} mkdir -p 2019"/{}"
1

This like should do the trick:

for FOLDER in `ls -l 2018/|grep '^d'|awk '{print $9}'`; do mkdir -p 2019/$FOLDER; done

OR

for FOLDER in `find 2018 -type d -exec basename {} \;|grep -v 2018`; do mkdir -p 2019/$FOLDER; done

I hope this helps.

  • The first version works; thanks. The second does not, as it collapses the tree structure, and puts all the subdirectories into 2019/. – smilingfrog Jan 2 at 17:38
  • It's weird the second option didn't work as it works for me. Anyways I'm glad it worked for you. Please mask the answer as correct so it can help others. – Manuel Florian Jan 2 at 19:13
  • 2
1

If you have mtree, you can do this:

$ mkdir 2019
$ mtree -cdp 2018 | mtree -Up 2019

If you don't have mtree, here's how to install Archie Cobbs' mtree port from GitHub on Ubuntu 16.04.5 LTS:

$ mkdir work; cd work
$ # adjust this URL to match the desired version from the GitHub page
$ wget https://s3.amazonaws.com/archie-public/mtree-port/mtree-1.0.4.tar.gz
$ tar xf mtree-1.0.4.tar.gz
$ cd mtree-1.0.4
$ cat README
mtree - Utility for creating and verifying file hierarchies

This is a port of the BSD mtree(1) utility.

See INSTALL for installation instructions.

See COPYING for license.

See CHANGES for change history.

Enjoy!

$ cat INSTALL

Simplified instructions:

    1. Ensure you have the following software packages installed:

        libopenssl-devel

    2. ./configure && make && sudo make install

Please see

    https://github.com/archiecobbs/mtree-port

for more information.

$ # I already had openssl installed in my Ubuntu VM, so I forged ahead:
$ ./configure
...
$ make
...
$ sudo make install
$ man mtree
...
$ which mtree
/usr/bin/mtree

I think the OpenSSL package name mentioned by the author may have changed since the instructions were created. On my system, libssl-dev was the package I needed to build mtree with SHA256 etc. support.

HTH,

Jim

  • I can't see how to install mtree on ubuntu. – smilingfrog Jan 3 at 19:04
  • 1
    @smilingfrog I located Archie Cobbs' GitHub project to port mtree to Linux, and updated my answer with instructions for installation on Ubuntu 16. – Jim L. Jan 3 at 19:57
0

Just:

cd 2018/
find * -type d -exec mkdir -p ../2019/{} \;

using the '*' instead of '.' will avoid selecting the 2018 directory itself.

Without cd-ing to directory, I would get the directories list into an array and substitute the year in mkdir command. For example:

# get list into an array, names can have spaces.
IFS=$'\r\n' dirs=($(find /some/path/2018/* -type d))
let i=0
while [ $i -lt ${#dirs[*]} ]; do
  mkdir -p "${dirs[$i]/2018/2019}"
  let i=i+1
done
  • +1 for find *; I didn't know that was an option. However, this does the same as my working script, and I am trying to figure out how to do it without changing into the directory. – smilingfrog Jan 2 at 17:23
  • just added a way to achieve this. – tonioc Jan 3 at 14:04

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.