Flattening directory hierarchy preserving directory names in new directory name












8















I basically want to go from this:



.
├── Alan Walker
│   ├── Different World
│   │ ├── 01 Intro.mp3
│   │ ├── 02 Lost Control.mp3
│   │ └── cover.jpg
│   └── Same World
│   ├── 01 Intro.mp3
│   └── 02 Found Control.mp3
├── Aurora
│   └── Infections Of A Different Kind Step 1
│   ├── 01 Queendom.lrc
│   ├── 02 Forgotten Love.lrc
│   └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses
    └── Use Your Illusion I
   ├── 01 Right Next Door To Hell.lrc
   ├── 01 Right Next Door To Hell.mp3
   ├── 02 Dust N' Bones.lrc
   └── 02 Dust N' Bones.mp3


to this:



.
├── Alan Walker - Different World
│ ├── 01 Intro.mp3
│ ├── 02 Lost Control.mp3
│ └── cover.jpg
├── Alan Walker - Same World
│ ├── 01 Intro.mp3
│ └── 02 Found Control.mp3
├── Aurora - Infections Of A Different Kind Step 1
│ ├── 01 Queendom.lrc
│ ├── 02 Forgotten Love.lrc
│ └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses - Use Your Illusion I
├── 01 Right Next Door To Hell.lrc
├── 01 Right Next Door To Hell.mp3
├── 02 Dust N' Bones.lrc
└── 02 Dust N' Bones.mp3


None of the existing solutions I could find included renaming the directory itself. It'd be great to be able to do this with zmv, but I can't figure out how to.










share|improve this question




















  • 2





    Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

    – rvs
    Jan 2 at 14:34






  • 2





    Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

    – nohillside
    Jan 2 at 14:52






  • 1





    @nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

    – aksh1618
    Jan 2 at 14:54
















8















I basically want to go from this:



.
├── Alan Walker
│   ├── Different World
│   │ ├── 01 Intro.mp3
│   │ ├── 02 Lost Control.mp3
│   │ └── cover.jpg
│   └── Same World
│   ├── 01 Intro.mp3
│   └── 02 Found Control.mp3
├── Aurora
│   └── Infections Of A Different Kind Step 1
│   ├── 01 Queendom.lrc
│   ├── 02 Forgotten Love.lrc
│   └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses
    └── Use Your Illusion I
   ├── 01 Right Next Door To Hell.lrc
   ├── 01 Right Next Door To Hell.mp3
   ├── 02 Dust N' Bones.lrc
   └── 02 Dust N' Bones.mp3


to this:



.
├── Alan Walker - Different World
│ ├── 01 Intro.mp3
│ ├── 02 Lost Control.mp3
│ └── cover.jpg
├── Alan Walker - Same World
│ ├── 01 Intro.mp3
│ └── 02 Found Control.mp3
├── Aurora - Infections Of A Different Kind Step 1
│ ├── 01 Queendom.lrc
│ ├── 02 Forgotten Love.lrc
│ └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses - Use Your Illusion I
├── 01 Right Next Door To Hell.lrc
├── 01 Right Next Door To Hell.mp3
├── 02 Dust N' Bones.lrc
└── 02 Dust N' Bones.mp3


None of the existing solutions I could find included renaming the directory itself. It'd be great to be able to do this with zmv, but I can't figure out how to.










share|improve this question




















  • 2





    Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

    – rvs
    Jan 2 at 14:34






  • 2





    Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

    – nohillside
    Jan 2 at 14:52






  • 1





    @nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

    – aksh1618
    Jan 2 at 14:54














8












8








8








I basically want to go from this:



.
├── Alan Walker
│   ├── Different World
│   │ ├── 01 Intro.mp3
│   │ ├── 02 Lost Control.mp3
│   │ └── cover.jpg
│   └── Same World
│   ├── 01 Intro.mp3
│   └── 02 Found Control.mp3
├── Aurora
│   └── Infections Of A Different Kind Step 1
│   ├── 01 Queendom.lrc
│   ├── 02 Forgotten Love.lrc
│   └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses
    └── Use Your Illusion I
   ├── 01 Right Next Door To Hell.lrc
   ├── 01 Right Next Door To Hell.mp3
   ├── 02 Dust N' Bones.lrc
   └── 02 Dust N' Bones.mp3


to this:



.
├── Alan Walker - Different World
│ ├── 01 Intro.mp3
│ ├── 02 Lost Control.mp3
│ └── cover.jpg
├── Alan Walker - Same World
│ ├── 01 Intro.mp3
│ └── 02 Found Control.mp3
├── Aurora - Infections Of A Different Kind Step 1
│ ├── 01 Queendom.lrc
│ ├── 02 Forgotten Love.lrc
│ └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses - Use Your Illusion I
├── 01 Right Next Door To Hell.lrc
├── 01 Right Next Door To Hell.mp3
├── 02 Dust N' Bones.lrc
└── 02 Dust N' Bones.mp3


None of the existing solutions I could find included renaming the directory itself. It'd be great to be able to do this with zmv, but I can't figure out how to.










share|improve this question
















I basically want to go from this:



.
├── Alan Walker
│   ├── Different World
│   │ ├── 01 Intro.mp3
│   │ ├── 02 Lost Control.mp3
│   │ └── cover.jpg
│   └── Same World
│   ├── 01 Intro.mp3
│   └── 02 Found Control.mp3
├── Aurora
│   └── Infections Of A Different Kind Step 1
│   ├── 01 Queendom.lrc
│   ├── 02 Forgotten Love.lrc
│   └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses
    └── Use Your Illusion I
   ├── 01 Right Next Door To Hell.lrc
   ├── 01 Right Next Door To Hell.mp3
   ├── 02 Dust N' Bones.lrc
   └── 02 Dust N' Bones.mp3


to this:



.
├── Alan Walker - Different World
│ ├── 01 Intro.mp3
│ ├── 02 Lost Control.mp3
│ └── cover.jpg
├── Alan Walker - Same World
│ ├── 01 Intro.mp3
│ └── 02 Found Control.mp3
├── Aurora - Infections Of A Different Kind Step 1
│ ├── 01 Queendom.lrc
│ ├── 02 Forgotten Love.lrc
│ └── 03 Gentle Earthquakes.mp3
└── Guns N' Roses - Use Your Illusion I
├── 01 Right Next Door To Hell.lrc
├── 01 Right Next Door To Hell.mp3
├── 02 Dust N' Bones.lrc
└── 02 Dust N' Bones.mp3


None of the existing solutions I could find included renaming the directory itself. It'd be great to be able to do this with zmv, but I can't figure out how to.







bash shell-script zsh directory rename






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 16:16









Kusalananda

124k16234385




124k16234385










asked Jan 2 at 14:11









aksh1618aksh1618

8710




8710








  • 2





    Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

    – rvs
    Jan 2 at 14:34






  • 2





    Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

    – nohillside
    Jan 2 at 14:52






  • 1





    @nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

    – aksh1618
    Jan 2 at 14:54














  • 2





    Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

    – rvs
    Jan 2 at 14:34






  • 2





    Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

    – nohillside
    Jan 2 at 14:52






  • 1





    @nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

    – aksh1618
    Jan 2 at 14:54








2




2





Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

– rvs
Jan 2 at 14:34





Not a full solution, so not an answer: easytag may let you do this, but only for audio files - I don't think it will move covers, etc.

– rvs
Jan 2 at 14:34




2




2





Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

– nohillside
Jan 2 at 14:52





Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?

– nohillside
Jan 2 at 14:52




1




1





@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

– aksh1618
Jan 2 at 14:54





@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.

– aksh1618
Jan 2 at 14:54










3 Answers
3






active

oldest

votes


















9














Zsh



Untested:



zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)


The second line removes all empty directories, even those that didn't have a file before. It's possible to work around this with a custom mv wrapper that records what directories it moves things from.



Note that this traverses symbolic links to directories in the current directory.



Linux rename utility



Untested.



rename / ' - ' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Perl rename script



Untested.



prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Here's a more complex approach that only removes directories that it renamed something from. Again, untested.



prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/





share|improve this answer
























  • Exactly what I was looking for! Thanks!

    – aksh1618
    Jan 6 at 11:28



















13














Something like this maybe?





#!/bin/sh

for topdir in */; do
topdir_name=$( basename "$topdir" )

for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )

newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done

rmdir "$topdir"
done


This goes through all the top-level directories in the current directory (the band names). For each such directory, it goes through its subdirectories (the album names). For each pair of band name and album name, a new directory is created and the files from the subdirectory are moved to it. The album subdirectories are removed when they have been processed, as are the original band top-level directories.



The rmdir calls will fail if any directory contains hidden filenames or if any of the new directories failed to be created.



This is totally untested code. Run it on a backed-up copy of your files.






share|improve this answer


























  • I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

    – aksh1618
    Jan 2 at 15:06






  • 10





    Put ot into a script, and -boom- it becomes a one-liner.

    – Hans-Martin Mosner
    Jan 2 at 15:24



















4














Strategically, rather than moving files, have you considered leaving the current structure in place and creating links for the new structure you want?



Tactically, a pattern that'll do the job goes like this:



find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c 
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}




  • find locates all directories exactly two levels deep from the current working directory, which should be the directory containing the bands: thus two levels deep are the album names underneath the band names.1


  • xargs consumes each path containing an album and calls out to the inline bash script.


  • bash -c '...' takes the album path as its first argument, breaking that path into two parts: the band ($b) and the album ($a). Finally, the script reassembles the names into the desired format and links the new directory name to the original directory.


Note that, in this example, the links would be created in the same directory from which you start, which also happens to be where the band names are.



You could - and should - tweak the ln strategy above to match your intent. mv with the right paths if you physically want to rearrange, or ln if you're wanting to create a convenience "view" over the media. The important parts inside the bash script are:





  • $b the band name. Always quote it: "$b".


  • $a the album name. Always quote it: "$a".


  • $1 the physical path to the album directory. Always quote it: "$1".




1 I believe m{ax,in}depth are supported by GNU and some BSD find, but not POSIX: in which case, rely on */* or similar shell gymnastics.






share|improve this answer



















  • 1





    I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

    – Thomas Zwaagstra
    Jan 2 at 20:20











  • @ThomasZwaagstra That's no different than moving the files

    – Darkhogg
    Jan 3 at 10:53






  • 1





    @Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

    – Thomas Zwaagstra
    Jan 3 at 23:15











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f492030%2fflattening-directory-hierarchy-preserving-directory-names-in-new-directory-name%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









9














Zsh



Untested:



zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)


The second line removes all empty directories, even those that didn't have a file before. It's possible to work around this with a custom mv wrapper that records what directories it moves things from.



Note that this traverses symbolic links to directories in the current directory.



Linux rename utility



Untested.



rename / ' - ' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Perl rename script



Untested.



prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Here's a more complex approach that only removes directories that it renamed something from. Again, untested.



prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/





share|improve this answer
























  • Exactly what I was looking for! Thanks!

    – aksh1618
    Jan 6 at 11:28
















9














Zsh



Untested:



zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)


The second line removes all empty directories, even those that didn't have a file before. It's possible to work around this with a custom mv wrapper that records what directories it moves things from.



Note that this traverses symbolic links to directories in the current directory.



Linux rename utility



Untested.



rename / ' - ' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Perl rename script



Untested.



prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Here's a more complex approach that only removes directories that it renamed something from. Again, untested.



prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/





share|improve this answer
























  • Exactly what I was looking for! Thanks!

    – aksh1618
    Jan 6 at 11:28














9












9








9







Zsh



Untested:



zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)


The second line removes all empty directories, even those that didn't have a file before. It's possible to work around this with a custom mv wrapper that records what directories it moves things from.



Note that this traverses symbolic links to directories in the current directory.



Linux rename utility



Untested.



rename / ' - ' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Perl rename script



Untested.



prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Here's a more complex approach that only removes directories that it renamed something from. Again, untested.



prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/





share|improve this answer













Zsh



Untested:



zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)


The second line removes all empty directories, even those that didn't have a file before. It's possible to work around this with a custom mv wrapper that records what directories it moves things from.



Note that this traverses symbolic links to directories in the current directory.



Linux rename utility



Untested.



rename / ' - ' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Perl rename script



Untested.



prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null


Note that this traverses symbolic links to directories in the current directory and in its subdirectories. The second line removes all empty directories, even those that didn't have a file before.



Here's a more complex approach that only removes directories that it renamed something from. Again, untested.



prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 2 at 18:43









GillesGilles

531k12810631591




531k12810631591













  • Exactly what I was looking for! Thanks!

    – aksh1618
    Jan 6 at 11:28



















  • Exactly what I was looking for! Thanks!

    – aksh1618
    Jan 6 at 11:28

















Exactly what I was looking for! Thanks!

– aksh1618
Jan 6 at 11:28





Exactly what I was looking for! Thanks!

– aksh1618
Jan 6 at 11:28













13














Something like this maybe?





#!/bin/sh

for topdir in */; do
topdir_name=$( basename "$topdir" )

for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )

newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done

rmdir "$topdir"
done


This goes through all the top-level directories in the current directory (the band names). For each such directory, it goes through its subdirectories (the album names). For each pair of band name and album name, a new directory is created and the files from the subdirectory are moved to it. The album subdirectories are removed when they have been processed, as are the original band top-level directories.



The rmdir calls will fail if any directory contains hidden filenames or if any of the new directories failed to be created.



This is totally untested code. Run it on a backed-up copy of your files.






share|improve this answer


























  • I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

    – aksh1618
    Jan 2 at 15:06






  • 10





    Put ot into a script, and -boom- it becomes a one-liner.

    – Hans-Martin Mosner
    Jan 2 at 15:24
















13














Something like this maybe?





#!/bin/sh

for topdir in */; do
topdir_name=$( basename "$topdir" )

for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )

newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done

rmdir "$topdir"
done


This goes through all the top-level directories in the current directory (the band names). For each such directory, it goes through its subdirectories (the album names). For each pair of band name and album name, a new directory is created and the files from the subdirectory are moved to it. The album subdirectories are removed when they have been processed, as are the original band top-level directories.



The rmdir calls will fail if any directory contains hidden filenames or if any of the new directories failed to be created.



This is totally untested code. Run it on a backed-up copy of your files.






share|improve this answer


























  • I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

    – aksh1618
    Jan 2 at 15:06






  • 10





    Put ot into a script, and -boom- it becomes a one-liner.

    – Hans-Martin Mosner
    Jan 2 at 15:24














13












13








13







Something like this maybe?





#!/bin/sh

for topdir in */; do
topdir_name=$( basename "$topdir" )

for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )

newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done

rmdir "$topdir"
done


This goes through all the top-level directories in the current directory (the band names). For each such directory, it goes through its subdirectories (the album names). For each pair of band name and album name, a new directory is created and the files from the subdirectory are moved to it. The album subdirectories are removed when they have been processed, as are the original band top-level directories.



The rmdir calls will fail if any directory contains hidden filenames or if any of the new directories failed to be created.



This is totally untested code. Run it on a backed-up copy of your files.






share|improve this answer















Something like this maybe?





#!/bin/sh

for topdir in */; do
topdir_name=$( basename "$topdir" )

for subdir in "$topdir"/*/; do
subdir_name=$( basename "$subdir" )

newdir="$topdir_name - $subdir_name"
if mkdir "$newdir"; then
mv "$subdir"/* "$newdir"
rmdir "$subdir"
fi
done

rmdir "$topdir"
done


This goes through all the top-level directories in the current directory (the band names). For each such directory, it goes through its subdirectories (the album names). For each pair of band name and album name, a new directory is created and the files from the subdirectory are moved to it. The album subdirectories are removed when they have been processed, as are the original band top-level directories.



The rmdir calls will fail if any directory contains hidden filenames or if any of the new directories failed to be created.



This is totally untested code. Run it on a backed-up copy of your files.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 at 19:36

























answered Jan 2 at 15:00









KusalanandaKusalananda

124k16234385




124k16234385













  • I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

    – aksh1618
    Jan 2 at 15:06






  • 10





    Put ot into a script, and -boom- it becomes a one-liner.

    – Hans-Martin Mosner
    Jan 2 at 15:24



















  • I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

    – aksh1618
    Jan 2 at 15:06






  • 10





    Put ot into a script, and -boom- it becomes a one-liner.

    – Hans-Martin Mosner
    Jan 2 at 15:24

















I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

– aksh1618
Jan 2 at 15:06





I mean, yes, something like would work, but I'm kinda looking for a one or two line solution, to run easily from terminal. Some find/sed/zmv magic :)

– aksh1618
Jan 2 at 15:06




10




10





Put ot into a script, and -boom- it becomes a one-liner.

– Hans-Martin Mosner
Jan 2 at 15:24





Put ot into a script, and -boom- it becomes a one-liner.

– Hans-Martin Mosner
Jan 2 at 15:24











4














Strategically, rather than moving files, have you considered leaving the current structure in place and creating links for the new structure you want?



Tactically, a pattern that'll do the job goes like this:



find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c 
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}




  • find locates all directories exactly two levels deep from the current working directory, which should be the directory containing the bands: thus two levels deep are the album names underneath the band names.1


  • xargs consumes each path containing an album and calls out to the inline bash script.


  • bash -c '...' takes the album path as its first argument, breaking that path into two parts: the band ($b) and the album ($a). Finally, the script reassembles the names into the desired format and links the new directory name to the original directory.


Note that, in this example, the links would be created in the same directory from which you start, which also happens to be where the band names are.



You could - and should - tweak the ln strategy above to match your intent. mv with the right paths if you physically want to rearrange, or ln if you're wanting to create a convenience "view" over the media. The important parts inside the bash script are:





  • $b the band name. Always quote it: "$b".


  • $a the album name. Always quote it: "$a".


  • $1 the physical path to the album directory. Always quote it: "$1".




1 I believe m{ax,in}depth are supported by GNU and some BSD find, but not POSIX: in which case, rely on */* or similar shell gymnastics.






share|improve this answer



















  • 1





    I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

    – Thomas Zwaagstra
    Jan 2 at 20:20











  • @ThomasZwaagstra That's no different than moving the files

    – Darkhogg
    Jan 3 at 10:53






  • 1





    @Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

    – Thomas Zwaagstra
    Jan 3 at 23:15
















4














Strategically, rather than moving files, have you considered leaving the current structure in place and creating links for the new structure you want?



Tactically, a pattern that'll do the job goes like this:



find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c 
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}




  • find locates all directories exactly two levels deep from the current working directory, which should be the directory containing the bands: thus two levels deep are the album names underneath the band names.1


  • xargs consumes each path containing an album and calls out to the inline bash script.


  • bash -c '...' takes the album path as its first argument, breaking that path into two parts: the band ($b) and the album ($a). Finally, the script reassembles the names into the desired format and links the new directory name to the original directory.


Note that, in this example, the links would be created in the same directory from which you start, which also happens to be where the band names are.



You could - and should - tweak the ln strategy above to match your intent. mv with the right paths if you physically want to rearrange, or ln if you're wanting to create a convenience "view" over the media. The important parts inside the bash script are:





  • $b the band name. Always quote it: "$b".


  • $a the album name. Always quote it: "$a".


  • $1 the physical path to the album directory. Always quote it: "$1".




1 I believe m{ax,in}depth are supported by GNU and some BSD find, but not POSIX: in which case, rely on */* or similar shell gymnastics.






share|improve this answer



















  • 1





    I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

    – Thomas Zwaagstra
    Jan 2 at 20:20











  • @ThomasZwaagstra That's no different than moving the files

    – Darkhogg
    Jan 3 at 10:53






  • 1





    @Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

    – Thomas Zwaagstra
    Jan 3 at 23:15














4












4








4







Strategically, rather than moving files, have you considered leaving the current structure in place and creating links for the new structure you want?



Tactically, a pattern that'll do the job goes like this:



find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c 
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}




  • find locates all directories exactly two levels deep from the current working directory, which should be the directory containing the bands: thus two levels deep are the album names underneath the band names.1


  • xargs consumes each path containing an album and calls out to the inline bash script.


  • bash -c '...' takes the album path as its first argument, breaking that path into two parts: the band ($b) and the album ($a). Finally, the script reassembles the names into the desired format and links the new directory name to the original directory.


Note that, in this example, the links would be created in the same directory from which you start, which also happens to be where the band names are.



You could - and should - tweak the ln strategy above to match your intent. mv with the right paths if you physically want to rearrange, or ln if you're wanting to create a convenience "view" over the media. The important parts inside the bash script are:





  • $b the band name. Always quote it: "$b".


  • $a the album name. Always quote it: "$a".


  • $1 the physical path to the album directory. Always quote it: "$1".




1 I believe m{ax,in}depth are supported by GNU and some BSD find, but not POSIX: in which case, rely on */* or similar shell gymnastics.






share|improve this answer













Strategically, rather than moving files, have you considered leaving the current structure in place and creating links for the new structure you want?



Tactically, a pattern that'll do the job goes like this:



find . -mindepth 2 -maxdepth 2 -type d -print0 | xargs -0n1 bash -c 
'b=$(basename "$(dirname "$1")"); a=$(basename "$1"); echo ln -s "$1" "$b-$a"' {}




  • find locates all directories exactly two levels deep from the current working directory, which should be the directory containing the bands: thus two levels deep are the album names underneath the band names.1


  • xargs consumes each path containing an album and calls out to the inline bash script.


  • bash -c '...' takes the album path as its first argument, breaking that path into two parts: the band ($b) and the album ($a). Finally, the script reassembles the names into the desired format and links the new directory name to the original directory.


Note that, in this example, the links would be created in the same directory from which you start, which also happens to be where the band names are.



You could - and should - tweak the ln strategy above to match your intent. mv with the right paths if you physically want to rearrange, or ln if you're wanting to create a convenience "view" over the media. The important parts inside the bash script are:





  • $b the band name. Always quote it: "$b".


  • $a the album name. Always quote it: "$a".


  • $1 the physical path to the album directory. Always quote it: "$1".




1 I believe m{ax,in}depth are supported by GNU and some BSD find, but not POSIX: in which case, rely on */* or similar shell gymnastics.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 2 at 16:31









bishopbishop

2,0662822




2,0662822








  • 1





    I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

    – Thomas Zwaagstra
    Jan 2 at 20:20











  • @ThomasZwaagstra That's no different than moving the files

    – Darkhogg
    Jan 3 at 10:53






  • 1





    @Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

    – Thomas Zwaagstra
    Jan 3 at 23:15














  • 1





    I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

    – Thomas Zwaagstra
    Jan 2 at 20:20











  • @ThomasZwaagstra That's no different than moving the files

    – Darkhogg
    Jan 3 at 10:53






  • 1





    @Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

    – Thomas Zwaagstra
    Jan 3 at 23:15








1




1





I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

– Thomas Zwaagstra
Jan 2 at 20:20





I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied

– Thomas Zwaagstra
Jan 2 at 20:20













@ThomasZwaagstra That's no different than moving the files

– Darkhogg
Jan 3 at 10:53





@ThomasZwaagstra That's no different than moving the files

– Darkhogg
Jan 3 at 10:53




1




1





@Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

– Thomas Zwaagstra
Jan 3 at 23:15





@Darkhogg Exactly! OP was looking for a 1-liner to move the files. Using hardlinks with this solution would nearly accomplish that, except you would have an intermediate "preview" stage before deleting the original files

– Thomas Zwaagstra
Jan 3 at 23:15


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f492030%2fflattening-directory-hierarchy-preserving-directory-names-in-new-directory-name%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

Npm cannot find a required file even through it is in the searched directory

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith