Recursively rename all the files without changing their extensions?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












How to recursively rename all the files in several layers of subdirectories without changing their extensions?



Below's a toned down version (to save room) of what I've got.
For argument's sake, I want all the files to have the same title, yet retain their original extension. There's never more than a single file per directory, so there's no chance of doubling up.



For simplicity, we'll just call them all foo, followed by their current extension.



So just to clarify:
Asset 1.pdf, Asset 1.png, Asset 1@4x.png, Asset 1.svg

Will become:
foo.pdf, foo.png, foo.png, foo.svg

And so on in that fashion.




I would typically use parameter expansion and a for loop, like:



for f in */*; do mv "$f" "$f%/*/foo.$f##*."; done 


But it's not recursive. So I would prefer to use something with find..-exec or similar.




~/Desktop/Project/Graphics/
├── Huge
│   ├── PDF
│   │   └── Asset 1.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── Asset 1.png
│   │   └── 4x
│   │   └── Asset 1@4x.png
│   └── SVG
│   └── Asset 1.svg
├── Large
│   ├── PDF
│   │   └── ProjectAsset 2.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 2.png
│   │   └── 4x
│   │   └── ProjectAsset 2@4x.png
│   └── SVG
│   └── ProjectAsset 2.svg
├── Medium
│   ├── PDF
│   │   └── ProjectAsset 3.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 3.png
│   │   └── 4x
│   │   └── ProjectAsset 3@4x.png
│   └── SVG
│   └── ProjectAsset 3.svg
├── Small
│   ├── PDF
│   │   └── ProjectAsset 4.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 4.png
│   │   └── 4x
│   │   └── ProjectAsset 4@4x.png
│   └── SVG
│   └── ProjectAsset 4.svg
└── Tiny
├── PDF
│   └── Asset 5.pdf
├── PNG
│   ├── 1x
│   │   └── Asset 5.png
│   └── 4x
│   └── Asset 5@4x.png
└── SVG
└── Asset 5.svg

30 directories, 20 files









share|improve this question























  • You can use a combination of find and GNU mv like described in this answer.
    – feliks
    3 hours ago











  • @feliks This system has mostly BSD utilities. But I think it is basically the same.
    – tjt263
    49 mins ago










  • @feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
    – tjt263
    31 mins ago














up vote
0
down vote

favorite












How to recursively rename all the files in several layers of subdirectories without changing their extensions?



Below's a toned down version (to save room) of what I've got.
For argument's sake, I want all the files to have the same title, yet retain their original extension. There's never more than a single file per directory, so there's no chance of doubling up.



For simplicity, we'll just call them all foo, followed by their current extension.



So just to clarify:
Asset 1.pdf, Asset 1.png, Asset 1@4x.png, Asset 1.svg

Will become:
foo.pdf, foo.png, foo.png, foo.svg

And so on in that fashion.




I would typically use parameter expansion and a for loop, like:



for f in */*; do mv "$f" "$f%/*/foo.$f##*."; done 


But it's not recursive. So I would prefer to use something with find..-exec or similar.




~/Desktop/Project/Graphics/
├── Huge
│   ├── PDF
│   │   └── Asset 1.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── Asset 1.png
│   │   └── 4x
│   │   └── Asset 1@4x.png
│   └── SVG
│   └── Asset 1.svg
├── Large
│   ├── PDF
│   │   └── ProjectAsset 2.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 2.png
│   │   └── 4x
│   │   └── ProjectAsset 2@4x.png
│   └── SVG
│   └── ProjectAsset 2.svg
├── Medium
│   ├── PDF
│   │   └── ProjectAsset 3.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 3.png
│   │   └── 4x
│   │   └── ProjectAsset 3@4x.png
│   └── SVG
│   └── ProjectAsset 3.svg
├── Small
│   ├── PDF
│   │   └── ProjectAsset 4.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 4.png
│   │   └── 4x
│   │   └── ProjectAsset 4@4x.png
│   └── SVG
│   └── ProjectAsset 4.svg
└── Tiny
├── PDF
│   └── Asset 5.pdf
├── PNG
│   ├── 1x
│   │   └── Asset 5.png
│   └── 4x
│   └── Asset 5@4x.png
└── SVG
└── Asset 5.svg

30 directories, 20 files









share|improve this question























  • You can use a combination of find and GNU mv like described in this answer.
    – feliks
    3 hours ago











  • @feliks This system has mostly BSD utilities. But I think it is basically the same.
    – tjt263
    49 mins ago










  • @feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
    – tjt263
    31 mins ago












up vote
0
down vote

favorite









up vote
0
down vote

favorite











How to recursively rename all the files in several layers of subdirectories without changing their extensions?



Below's a toned down version (to save room) of what I've got.
For argument's sake, I want all the files to have the same title, yet retain their original extension. There's never more than a single file per directory, so there's no chance of doubling up.



For simplicity, we'll just call them all foo, followed by their current extension.



So just to clarify:
Asset 1.pdf, Asset 1.png, Asset 1@4x.png, Asset 1.svg

Will become:
foo.pdf, foo.png, foo.png, foo.svg

And so on in that fashion.




I would typically use parameter expansion and a for loop, like:



for f in */*; do mv "$f" "$f%/*/foo.$f##*."; done 


But it's not recursive. So I would prefer to use something with find..-exec or similar.




~/Desktop/Project/Graphics/
├── Huge
│   ├── PDF
│   │   └── Asset 1.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── Asset 1.png
│   │   └── 4x
│   │   └── Asset 1@4x.png
│   └── SVG
│   └── Asset 1.svg
├── Large
│   ├── PDF
│   │   └── ProjectAsset 2.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 2.png
│   │   └── 4x
│   │   └── ProjectAsset 2@4x.png
│   └── SVG
│   └── ProjectAsset 2.svg
├── Medium
│   ├── PDF
│   │   └── ProjectAsset 3.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 3.png
│   │   └── 4x
│   │   └── ProjectAsset 3@4x.png
│   └── SVG
│   └── ProjectAsset 3.svg
├── Small
│   ├── PDF
│   │   └── ProjectAsset 4.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 4.png
│   │   └── 4x
│   │   └── ProjectAsset 4@4x.png
│   └── SVG
│   └── ProjectAsset 4.svg
└── Tiny
├── PDF
│   └── Asset 5.pdf
├── PNG
│   ├── 1x
│   │   └── Asset 5.png
│   └── 4x
│   └── Asset 5@4x.png
└── SVG
└── Asset 5.svg

30 directories, 20 files









share|improve this question















How to recursively rename all the files in several layers of subdirectories without changing their extensions?



Below's a toned down version (to save room) of what I've got.
For argument's sake, I want all the files to have the same title, yet retain their original extension. There's never more than a single file per directory, so there's no chance of doubling up.



For simplicity, we'll just call them all foo, followed by their current extension.



So just to clarify:
Asset 1.pdf, Asset 1.png, Asset 1@4x.png, Asset 1.svg

Will become:
foo.pdf, foo.png, foo.png, foo.svg

And so on in that fashion.




I would typically use parameter expansion and a for loop, like:



for f in */*; do mv "$f" "$f%/*/foo.$f##*."; done 


But it's not recursive. So I would prefer to use something with find..-exec or similar.




~/Desktop/Project/Graphics/
├── Huge
│   ├── PDF
│   │   └── Asset 1.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── Asset 1.png
│   │   └── 4x
│   │   └── Asset 1@4x.png
│   └── SVG
│   └── Asset 1.svg
├── Large
│   ├── PDF
│   │   └── ProjectAsset 2.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 2.png
│   │   └── 4x
│   │   └── ProjectAsset 2@4x.png
│   └── SVG
│   └── ProjectAsset 2.svg
├── Medium
│   ├── PDF
│   │   └── ProjectAsset 3.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 3.png
│   │   └── 4x
│   │   └── ProjectAsset 3@4x.png
│   └── SVG
│   └── ProjectAsset 3.svg
├── Small
│   ├── PDF
│   │   └── ProjectAsset 4.pdf
│   ├── PNG
│   │   ├── 1x
│   │   │   └── ProjectAsset 4.png
│   │   └── 4x
│   │   └── ProjectAsset 4@4x.png
│   └── SVG
│   └── ProjectAsset 4.svg
└── Tiny
├── PDF
│   └── Asset 5.pdf
├── PNG
│   ├── 1x
│   │   └── Asset 5.png
│   └── 4x
│   └── Asset 5@4x.png
└── SVG
└── Asset 5.svg

30 directories, 20 files






files find rename mv recursive






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 4 mins ago









don_crissti

48k15126156




48k15126156










asked 8 hours ago









tjt263

5101420




5101420











  • You can use a combination of find and GNU mv like described in this answer.
    – feliks
    3 hours ago











  • @feliks This system has mostly BSD utilities. But I think it is basically the same.
    – tjt263
    49 mins ago










  • @feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
    – tjt263
    31 mins ago
















  • You can use a combination of find and GNU mv like described in this answer.
    – feliks
    3 hours ago











  • @feliks This system has mostly BSD utilities. But I think it is basically the same.
    – tjt263
    49 mins ago










  • @feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
    – tjt263
    31 mins ago















You can use a combination of find and GNU mv like described in this answer.
– feliks
3 hours ago





You can use a combination of find and GNU mv like described in this answer.
– feliks
3 hours ago













@feliks This system has mostly BSD utilities. But I think it is basically the same.
– tjt263
49 mins ago




@feliks This system has mostly BSD utilities. But I think it is basically the same.
– tjt263
49 mins ago












@feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
– tjt263
31 mins ago




@feliks useful link, but the challenge lies in getting find x -exec y ; to play nicely with "$parameter%/*/foo.$expansion##*.", etc.
– tjt263
31 mins ago










2 Answers
2






active

oldest

votes

















up vote
0
down vote













Maybe I'm oversimplifying, but, if you know the max depth of the directory hierarchy (here: 3), why not



for f in */* */*/* */*/*/*; do ... ; done 


adding some error checking?






share|improve this answer




















  • I don't think it works like that, does it?I think I'm missing something
    – tjt263
    4 hours ago










  • Did you give it a try? Worked for me, going through all the subdirectory levels.
    – RudiC
    3 hours ago










  • Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
    – tjt263
    51 mins ago


















up vote
0
down vote













It's very similar with find...-exec: invoke a shell so that you can use parameter expansion, extract the PARENT directory and the EXTENSION so that you can construct the new filename as PARENT/NAME.EXTENSION and then move/rename:



find target_dir -type f -exec sh -c '
h=$1%/*; mv "$1" "$h/NAME.$1##*."' sh ;


If you want to dry-run the above, insert an echo before the mv...





share




















    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',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    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%2f476694%2frecursively-rename-all-the-files-without-changing-their-extensions%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Maybe I'm oversimplifying, but, if you know the max depth of the directory hierarchy (here: 3), why not



    for f in */* */*/* */*/*/*; do ... ; done 


    adding some error checking?






    share|improve this answer




















    • I don't think it works like that, does it?I think I'm missing something
      – tjt263
      4 hours ago










    • Did you give it a try? Worked for me, going through all the subdirectory levels.
      – RudiC
      3 hours ago










    • Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
      – tjt263
      51 mins ago















    up vote
    0
    down vote













    Maybe I'm oversimplifying, but, if you know the max depth of the directory hierarchy (here: 3), why not



    for f in */* */*/* */*/*/*; do ... ; done 


    adding some error checking?






    share|improve this answer




















    • I don't think it works like that, does it?I think I'm missing something
      – tjt263
      4 hours ago










    • Did you give it a try? Worked for me, going through all the subdirectory levels.
      – RudiC
      3 hours ago










    • Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
      – tjt263
      51 mins ago













    up vote
    0
    down vote










    up vote
    0
    down vote









    Maybe I'm oversimplifying, but, if you know the max depth of the directory hierarchy (here: 3), why not



    for f in */* */*/* */*/*/*; do ... ; done 


    adding some error checking?






    share|improve this answer












    Maybe I'm oversimplifying, but, if you know the max depth of the directory hierarchy (here: 3), why not



    for f in */* */*/* */*/*/*; do ... ; done 


    adding some error checking?







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 4 hours ago









    RudiC

    2,276110




    2,276110











    • I don't think it works like that, does it?I think I'm missing something
      – tjt263
      4 hours ago










    • Did you give it a try? Worked for me, going through all the subdirectory levels.
      – RudiC
      3 hours ago










    • Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
      – tjt263
      51 mins ago

















    • I don't think it works like that, does it?I think I'm missing something
      – tjt263
      4 hours ago










    • Did you give it a try? Worked for me, going through all the subdirectory levels.
      – RudiC
      3 hours ago










    • Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
      – tjt263
      51 mins ago
















    I don't think it works like that, does it?I think I'm missing something
    – tjt263
    4 hours ago




    I don't think it works like that, does it?I think I'm missing something
    – tjt263
    4 hours ago












    Did you give it a try? Worked for me, going through all the subdirectory levels.
    – RudiC
    3 hours ago




    Did you give it a try? Worked for me, going through all the subdirectory levels.
    – RudiC
    3 hours ago












    Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
    – tjt263
    51 mins ago





    Not yet. Wouldn't it just be */*/* though? Also, you omitted a significant chunk of the command line. Ideally, I would incorporate find too, so it could be scripted regardless of recursion depth. But thanks, I appreciate your input.
    – tjt263
    51 mins ago













    up vote
    0
    down vote













    It's very similar with find...-exec: invoke a shell so that you can use parameter expansion, extract the PARENT directory and the EXTENSION so that you can construct the new filename as PARENT/NAME.EXTENSION and then move/rename:



    find target_dir -type f -exec sh -c '
    h=$1%/*; mv "$1" "$h/NAME.$1##*."' sh ;


    If you want to dry-run the above, insert an echo before the mv...





    share
























      up vote
      0
      down vote













      It's very similar with find...-exec: invoke a shell so that you can use parameter expansion, extract the PARENT directory and the EXTENSION so that you can construct the new filename as PARENT/NAME.EXTENSION and then move/rename:



      find target_dir -type f -exec sh -c '
      h=$1%/*; mv "$1" "$h/NAME.$1##*."' sh ;


      If you want to dry-run the above, insert an echo before the mv...





      share






















        up vote
        0
        down vote










        up vote
        0
        down vote









        It's very similar with find...-exec: invoke a shell so that you can use parameter expansion, extract the PARENT directory and the EXTENSION so that you can construct the new filename as PARENT/NAME.EXTENSION and then move/rename:



        find target_dir -type f -exec sh -c '
        h=$1%/*; mv "$1" "$h/NAME.$1##*."' sh ;


        If you want to dry-run the above, insert an echo before the mv...





        share












        It's very similar with find...-exec: invoke a shell so that you can use parameter expansion, extract the PARENT directory and the EXTENSION so that you can construct the new filename as PARENT/NAME.EXTENSION and then move/rename:



        find target_dir -type f -exec sh -c '
        h=$1%/*; mv "$1" "$h/NAME.$1##*."' sh ;


        If you want to dry-run the above, insert an echo before the mv...






        share











        share


        share










        answered 6 mins ago









        don_crissti

        48k15126156




        48k15126156



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f476694%2frecursively-rename-all-the-files-without-changing-their-extensions%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)