Flattening directory hierarchy preserving directory names in new directory name
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
add a comment |
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
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
yesterday
2
Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?
– nohillside
yesterday
1
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday
add a comment |
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
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
bash shell-script zsh directory rename
edited 11 hours ago
Kusalananda
122k16230374
122k16230374
asked yesterday
aksh1618
506
506
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
yesterday
2
Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?
– nohillside
yesterday
1
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday
add a comment |
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
yesterday
2
Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?
– nohillside
yesterday
1
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday
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
yesterday
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
yesterday
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
yesterday
Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?
– nohillside
yesterday
1
1
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday
add a comment |
3 Answers
3
active
oldest
votes
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.
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
yesterday
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
add a comment |
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}' */*/
add a comment |
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.
1
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
yesterday
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
add a comment |
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.
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
yesterday
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
add a comment |
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.
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.
edited yesterday
answered yesterday
Kusalananda
122k16230374
122k16230374
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
yesterday
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
add a comment |
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
yesterday
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
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
yesterday
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
yesterday
10
10
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
Put ot into a script, and -boom- it becomes a one-liner.
– Hans-Martin Mosner
yesterday
add a comment |
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}' */*/
add a comment |
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}' */*/
add a comment |
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}' */*/
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}' */*/
answered yesterday
Gilles
529k12810601585
529k12810601585
add a comment |
add a comment |
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.
1
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
add a comment |
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.
1
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
add a comment |
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.
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.
answered yesterday
bishop
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
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
add a comment |
1
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
1
1
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
I like this answer... you could also make hardlinks, then delete the old folder structure when you're satisfied
– Thomas Zwaagstra
yesterday
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
@ThomasZwaagstra That's no different than moving the files
– Darkhogg
16 hours ago
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
4 hours ago
@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
4 hours ago
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
yesterday
2
Could there be more than one album for a specific artist within one artist directory? Is the structure always three levels deep?
– nohillside
yesterday
1
@nohillside Yes, There can be more than one album for an artist. And yes, the structure is always three levels deep.
– aksh1618
yesterday