2

I have a directory tree where the path elements correspond to specific properties of the file at a particular path. For example, something like this:

$ tree 
. ─ a ─ 1 ─ y ─ 334f
│   │   └── z ─ 6410
│   └── 2 ─ y ─ e776
└── b ─ 1 ─ y ─ 9828
    └── 2 ─ y ─ 0149
        └── z ─ 563a

I want to change the order of the path elements to put the (x|y) part first, then (1|2), then (a|b). (For example, ./a/1/y/334f should become ./y/1/a/334f.)

The complete final tree should be:

$ tree
. ─ y ─ 1 ─ a ─ 334f
│   │   └── b ─ 9828
│   └── 2 ─ a ─ e776
│       └── b ─ 0149
└── z ─ 1 ─ a ─ 6410
    └── 2 ─ b ─ 563a

How do I do this?

  • Since 'tree' is a representation of the directory structure it wont do what you want unless you want to mv all the files and then redraw the tree. Is that what you want? Or are you actually looking to draw an abstract tree based upon a set of relationships? Using the path elements as you would use fields in a database? – bu5hman Nov 21 '17 at 18:15
  • @bu5hman I'm looking to either move all the files, or (if it's simpler) create a new tree full of symbolic links to the original files. – AJMansfield Nov 21 '17 at 18:34
  • Similar to unix.stackexchange.com/a/266623/100397 – roaima Nov 21 '17 at 23:48
3

Create the target directories:

for d in */*/*;do mkdir -p $(echo $d | sed -r 's:(.+)/(.+)/(.+):\3/\2/\1/:'); done

Move the files:

for d in */*/*;do mv $d/* $(echo $d | sed -r 's:(.+)/(.+)/(.+):\3/\2/\1/:'); done

(this version wil complain that there are no files in the directories created in step #1, you can improve on the */*/* or create the target directories elsewhere)

  • Why not store the path? for oldPath in */*/*; do newPath=$(sed -r 's:(.+)/(.+)/(.+):\3/\2/\1/:' <<< $oldPath) ; mkdir -p $newPath; mv $oldPath/* $newPath; done – bu5hman Nov 22 '17 at 4:24
  • @bu5hman I a script I would have done so, but when trying things on a command line I prefer self-standing one-liners. – xenoid Nov 22 '17 at 7:26
  • A matter of taste, but whenever I do a bulk mv or rm I like to make a dry run and check the output by echo ing it first. Experience (read this as 'screaming and banging my head against the wall after losing / overwriting data') has led me to exercise a little caution. Even with apparently 'harmless' one-liners...... :-( – bu5hman Nov 22 '17 at 14:39

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.