Rename file names in multiple directories

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











up vote
1
down vote

favorite












I have several directories with files out of sequence because the titles are displayed before the file number. I want to match and replace the end of all the files, minus the extension, so the number is at the beginning like so.



From this;



A guide to perfect eggs-456704.mp4
Boil an egg-456702.mp4
How to ruin scrambled eggs-456703.mp4
Make green eggs and ham-456701.mp4
Poached eggs-456705.mp4


To this:



456701-Make green eggs and ham.mp4
456702-Boil an egg.mp4
456703-How to ruin scrambled eggs.mp4
456704-A guide to perfect eggs.mp4
456705-Poached eggs.mp4


The titles are random in length for each file with spaces, the numbers are 6 digits before the ".mp4" extension but preceded by a dash after the title.







share|improve this question


























    up vote
    1
    down vote

    favorite












    I have several directories with files out of sequence because the titles are displayed before the file number. I want to match and replace the end of all the files, minus the extension, so the number is at the beginning like so.



    From this;



    A guide to perfect eggs-456704.mp4
    Boil an egg-456702.mp4
    How to ruin scrambled eggs-456703.mp4
    Make green eggs and ham-456701.mp4
    Poached eggs-456705.mp4


    To this:



    456701-Make green eggs and ham.mp4
    456702-Boil an egg.mp4
    456703-How to ruin scrambled eggs.mp4
    456704-A guide to perfect eggs.mp4
    456705-Poached eggs.mp4


    The titles are random in length for each file with spaces, the numbers are 6 digits before the ".mp4" extension but preceded by a dash after the title.







    share|improve this question
























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have several directories with files out of sequence because the titles are displayed before the file number. I want to match and replace the end of all the files, minus the extension, so the number is at the beginning like so.



      From this;



      A guide to perfect eggs-456704.mp4
      Boil an egg-456702.mp4
      How to ruin scrambled eggs-456703.mp4
      Make green eggs and ham-456701.mp4
      Poached eggs-456705.mp4


      To this:



      456701-Make green eggs and ham.mp4
      456702-Boil an egg.mp4
      456703-How to ruin scrambled eggs.mp4
      456704-A guide to perfect eggs.mp4
      456705-Poached eggs.mp4


      The titles are random in length for each file with spaces, the numbers are 6 digits before the ".mp4" extension but preceded by a dash after the title.







      share|improve this question














      I have several directories with files out of sequence because the titles are displayed before the file number. I want to match and replace the end of all the files, minus the extension, so the number is at the beginning like so.



      From this;



      A guide to perfect eggs-456704.mp4
      Boil an egg-456702.mp4
      How to ruin scrambled eggs-456703.mp4
      Make green eggs and ham-456701.mp4
      Poached eggs-456705.mp4


      To this:



      456701-Make green eggs and ham.mp4
      456702-Boil an egg.mp4
      456703-How to ruin scrambled eggs.mp4
      456704-A guide to perfect eggs.mp4
      456705-Poached eggs.mp4


      The titles are random in length for each file with spaces, the numbers are 6 digits before the ".mp4" extension but preceded by a dash after the title.









      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 16 '17 at 15:04









      αғsнιη

      15.6k92563




      15.6k92563










      asked Oct 16 '17 at 13:14









      dawja

      285




      285




















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          Here you have a way of doing this. It is untested



          #!/bin/bash

          files=(*file)

          for f in "$files[@]"
          do
          get_ext="$f##*."
          no_ext="$f%-*"
          n="$f##*-" nn="$n%.*"
          mv "$f" "$nn-$no_ext.$get_ext"
          done





          share|improve this answer




















          • OP mentioned in multiple directories, so for each directories this script should be executed separately ?
            – Î±Ò“sнιη
            Oct 16 '17 at 17:30











          • @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
            – Valentin B
            Oct 16 '17 at 18:09

















          up vote
          1
          down vote













          Using find and Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.



          find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "$1//[^0-9]-$1//[-0-9]"' _ '' ;


          • With $1//[^0-9] we are removing everything except a number; The // is global replacement syntax while / is only for first occurrence of number.


          • Then a dash/hyphe -, and with $1//[-0-9] we are removing everything which is a - or number (again assuming only one - and numerical part is there in files name).


          We used -exec in above command which is not secure for some reasons1, 2 and here because with Shell Substitution Expansion it will take file's path and cause unexpected rename + it will drop all dashes - in files name!



          At the end don't forget to remove the echo above in commands to have actual rename where it used to dry run.




          find . -type f -name "*.mp4" -execdir sh -c '
          n="$1##*-";fn="$1%-*";
          echo mv -v "$1" "$n%.*-$fn##*/.mp4" ' _ '' ;


          Same as previous command but here we used shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion and this will grantee to keep all dashes - untouched within filesname if any like a file-with -- here-006.file except the last one which should be drop.



          We are looking for the files only -type f ends with .mp4 and with -execdir here, find is changing the current directory to the directory where a file found then execute the sh -c ' ... ' within that directory itself.



          • With n="$1##*-" "cut-up-to-last-prefix": we are removing everything from the begging of filename until last dash - seen and - itself and assign to variable n; The $1 or $1 is the relative path to ./fileName to the current directory by -execdir sh -c '...' _ '' ; returns.



          • With fn="$1%-*" "cut-up-to-first-suffix": We are removing everything from end of filename until first dash - seen and - itself and assign to variable fn.



            Now n="456704.mp4" and nf="./A guide to perfect eggs" (assuming for first file). Then;



          • With $n%.*- we are removing everything from end of fileName until first dot . seen and . itself and then added a dash -. So this will result only digits part of fileName 456704.



          • With $fn##*/.mp4 we are removing everything from begging of fileName until last slash / seen and / itself and then added .mp4 at the end. So this will result A guide to perfect eggs.mp4.





          1What are the security issues and race conditions in using find -exec?
          2Why using the '-execdir' action is insecure for directory which is in the PATH?






          share|improve this answer





























            up vote
            0
            down vote













            set "a file blah blah-004.file" 
            "b file blah blah blah-002.file"
            "c file blahh blah-003.file"
            "d file blah blah blah blabby blah-001.file"
            "e file blah-005.file"

            for name; do
            old=$name # save old name
            ext=$name##*. # take extension
            name=$name%.* # remove extension
            number=$name##*- # take number
            name=$name%-* # remove number
            new="$number-$name.$ext" # set new name
            echo mv "$old" "$new" # test rename
            done


            Remove the last echo, if it works.






            share|improve this answer




















            • What if there were hundreds of files?
              – Î±Ò“sнιη
              Oct 16 '17 at 17:36










            • @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
              – ceving
              Oct 16 '17 at 20:11











            • You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
              – Î±Ò“sнιη
              Oct 17 '17 at 9:10










            • Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
              – ceving
              Oct 17 '17 at 9:16


















            up vote
            0
            down vote













            Alternative find + prename (Perl rename) solution:



            find -type f -exec prename 's/^(.+?)([^/]+)-([0-9]+)(.[^.]+)$/$1$3-$2$4/' '' ;





            share|improve this answer


















            • 1




              @αғsнιη, if it's just for dashes - see my simple update
              – RomanPerekhrest
              Oct 16 '17 at 18:36










            • Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
              – Î±Ò“sнιη
              Oct 16 '17 at 18:41











            • @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
              – RomanPerekhrest
              Oct 16 '17 at 18:44










            • a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
              – Î±Ò“sнιη
              Oct 17 '17 at 9:11

















            up vote
            0
            down vote













            This is a portable sh implementation.



            find . -name "*[0-9].mp4" |
            sed "s/(.*/)(.*)-([0-9]*).mp4/'12-3.mp4' '13-2.mp4'/" |
            xargs -p -L 1 mv -v


            The find command is pretty straightforward: it will return only .mp4 files that contain at least one digit before the extension.



            The sed command duplicates the filename, sorrounding each filename with single quotes, and then the second filename gets the digit part moved between the relative file path and the filename accordingly (e.g., './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').



            The resulting list of current and new filenames are then passed to the xargs command, which will execute mv -v. The -L 1 option is needed so that xarg processes one line at a time. You can remove the -p option from this command and change the options that mv should use.



            I tested this implementation with your file list on Ubuntu bash, sh, and Mac OS High Sierra bash and sh, placing files in different subdirectories and adding a few files that didn't qualify.






            share|improve this answer




















              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%2f398409%2frename-file-names-in-multiple-directories%23new-answer', 'question_page');

              );

              Post as a guest






























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              0
              down vote



              accepted










              Here you have a way of doing this. It is untested



              #!/bin/bash

              files=(*file)

              for f in "$files[@]"
              do
              get_ext="$f##*."
              no_ext="$f%-*"
              n="$f##*-" nn="$n%.*"
              mv "$f" "$nn-$no_ext.$get_ext"
              done





              share|improve this answer




















              • OP mentioned in multiple directories, so for each directories this script should be executed separately ?
                – Î±Ò“sнιη
                Oct 16 '17 at 17:30











              • @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
                – Valentin B
                Oct 16 '17 at 18:09














              up vote
              0
              down vote



              accepted










              Here you have a way of doing this. It is untested



              #!/bin/bash

              files=(*file)

              for f in "$files[@]"
              do
              get_ext="$f##*."
              no_ext="$f%-*"
              n="$f##*-" nn="$n%.*"
              mv "$f" "$nn-$no_ext.$get_ext"
              done





              share|improve this answer




















              • OP mentioned in multiple directories, so for each directories this script should be executed separately ?
                – Î±Ò“sнιη
                Oct 16 '17 at 17:30











              • @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
                – Valentin B
                Oct 16 '17 at 18:09












              up vote
              0
              down vote



              accepted







              up vote
              0
              down vote



              accepted






              Here you have a way of doing this. It is untested



              #!/bin/bash

              files=(*file)

              for f in "$files[@]"
              do
              get_ext="$f##*."
              no_ext="$f%-*"
              n="$f##*-" nn="$n%.*"
              mv "$f" "$nn-$no_ext.$get_ext"
              done





              share|improve this answer












              Here you have a way of doing this. It is untested



              #!/bin/bash

              files=(*file)

              for f in "$files[@]"
              do
              get_ext="$f##*."
              no_ext="$f%-*"
              n="$f##*-" nn="$n%.*"
              mv "$f" "$nn-$no_ext.$get_ext"
              done






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Oct 16 '17 at 13:49









              Valentin B

              5,51611527




              5,51611527











              • OP mentioned in multiple directories, so for each directories this script should be executed separately ?
                – Î±Ò“sнιη
                Oct 16 '17 at 17:30











              • @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
                – Valentin B
                Oct 16 '17 at 18:09
















              • OP mentioned in multiple directories, so for each directories this script should be executed separately ?
                – Î±Ò“sнιη
                Oct 16 '17 at 17:30











              • @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
                – Valentin B
                Oct 16 '17 at 18:09















              OP mentioned in multiple directories, so for each directories this script should be executed separately ?
              – Î±Ò“sнιη
              Oct 16 '17 at 17:30





              OP mentioned in multiple directories, so for each directories this script should be executed separately ?
              – Î±Ò“sнιη
              Oct 16 '17 at 17:30













              @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
              – Valentin B
              Oct 16 '17 at 18:09




              @αғsнιη you are correct. I kinda wrote it in a hurry and didn't read the question properly. For multiple directories, your code is much better. Your find might need a -name '*.mp4' otherwise files with mp3 extension might also be moved.
              – Valentin B
              Oct 16 '17 at 18:09












              up vote
              1
              down vote













              Using find and Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.



              find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "$1//[^0-9]-$1//[-0-9]"' _ '' ;


              • With $1//[^0-9] we are removing everything except a number; The // is global replacement syntax while / is only for first occurrence of number.


              • Then a dash/hyphe -, and with $1//[-0-9] we are removing everything which is a - or number (again assuming only one - and numerical part is there in files name).


              We used -exec in above command which is not secure for some reasons1, 2 and here because with Shell Substitution Expansion it will take file's path and cause unexpected rename + it will drop all dashes - in files name!



              At the end don't forget to remove the echo above in commands to have actual rename where it used to dry run.




              find . -type f -name "*.mp4" -execdir sh -c '
              n="$1##*-";fn="$1%-*";
              echo mv -v "$1" "$n%.*-$fn##*/.mp4" ' _ '' ;


              Same as previous command but here we used shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion and this will grantee to keep all dashes - untouched within filesname if any like a file-with -- here-006.file except the last one which should be drop.



              We are looking for the files only -type f ends with .mp4 and with -execdir here, find is changing the current directory to the directory where a file found then execute the sh -c ' ... ' within that directory itself.



              • With n="$1##*-" "cut-up-to-last-prefix": we are removing everything from the begging of filename until last dash - seen and - itself and assign to variable n; The $1 or $1 is the relative path to ./fileName to the current directory by -execdir sh -c '...' _ '' ; returns.



              • With fn="$1%-*" "cut-up-to-first-suffix": We are removing everything from end of filename until first dash - seen and - itself and assign to variable fn.



                Now n="456704.mp4" and nf="./A guide to perfect eggs" (assuming for first file). Then;



              • With $n%.*- we are removing everything from end of fileName until first dot . seen and . itself and then added a dash -. So this will result only digits part of fileName 456704.



              • With $fn##*/.mp4 we are removing everything from begging of fileName until last slash / seen and / itself and then added .mp4 at the end. So this will result A guide to perfect eggs.mp4.





              1What are the security issues and race conditions in using find -exec?
              2Why using the '-execdir' action is insecure for directory which is in the PATH?






              share|improve this answer


























                up vote
                1
                down vote













                Using find and Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.



                find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "$1//[^0-9]-$1//[-0-9]"' _ '' ;


                • With $1//[^0-9] we are removing everything except a number; The // is global replacement syntax while / is only for first occurrence of number.


                • Then a dash/hyphe -, and with $1//[-0-9] we are removing everything which is a - or number (again assuming only one - and numerical part is there in files name).


                We used -exec in above command which is not secure for some reasons1, 2 and here because with Shell Substitution Expansion it will take file's path and cause unexpected rename + it will drop all dashes - in files name!



                At the end don't forget to remove the echo above in commands to have actual rename where it used to dry run.




                find . -type f -name "*.mp4" -execdir sh -c '
                n="$1##*-";fn="$1%-*";
                echo mv -v "$1" "$n%.*-$fn##*/.mp4" ' _ '' ;


                Same as previous command but here we used shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion and this will grantee to keep all dashes - untouched within filesname if any like a file-with -- here-006.file except the last one which should be drop.



                We are looking for the files only -type f ends with .mp4 and with -execdir here, find is changing the current directory to the directory where a file found then execute the sh -c ' ... ' within that directory itself.



                • With n="$1##*-" "cut-up-to-last-prefix": we are removing everything from the begging of filename until last dash - seen and - itself and assign to variable n; The $1 or $1 is the relative path to ./fileName to the current directory by -execdir sh -c '...' _ '' ; returns.



                • With fn="$1%-*" "cut-up-to-first-suffix": We are removing everything from end of filename until first dash - seen and - itself and assign to variable fn.



                  Now n="456704.mp4" and nf="./A guide to perfect eggs" (assuming for first file). Then;



                • With $n%.*- we are removing everything from end of fileName until first dot . seen and . itself and then added a dash -. So this will result only digits part of fileName 456704.



                • With $fn##*/.mp4 we are removing everything from begging of fileName until last slash / seen and / itself and then added .mp4 at the end. So this will result A guide to perfect eggs.mp4.





                1What are the security issues and race conditions in using find -exec?
                2Why using the '-execdir' action is insecure for directory which is in the PATH?






                share|improve this answer
























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Using find and Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.



                  find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "$1//[^0-9]-$1//[-0-9]"' _ '' ;


                  • With $1//[^0-9] we are removing everything except a number; The // is global replacement syntax while / is only for first occurrence of number.


                  • Then a dash/hyphe -, and with $1//[-0-9] we are removing everything which is a - or number (again assuming only one - and numerical part is there in files name).


                  We used -exec in above command which is not secure for some reasons1, 2 and here because with Shell Substitution Expansion it will take file's path and cause unexpected rename + it will drop all dashes - in files name!



                  At the end don't forget to remove the echo above in commands to have actual rename where it used to dry run.




                  find . -type f -name "*.mp4" -execdir sh -c '
                  n="$1##*-";fn="$1%-*";
                  echo mv -v "$1" "$n%.*-$fn##*/.mp4" ' _ '' ;


                  Same as previous command but here we used shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion and this will grantee to keep all dashes - untouched within filesname if any like a file-with -- here-006.file except the last one which should be drop.



                  We are looking for the files only -type f ends with .mp4 and with -execdir here, find is changing the current directory to the directory where a file found then execute the sh -c ' ... ' within that directory itself.



                  • With n="$1##*-" "cut-up-to-last-prefix": we are removing everything from the begging of filename until last dash - seen and - itself and assign to variable n; The $1 or $1 is the relative path to ./fileName to the current directory by -execdir sh -c '...' _ '' ; returns.



                  • With fn="$1%-*" "cut-up-to-first-suffix": We are removing everything from end of filename until first dash - seen and - itself and assign to variable fn.



                    Now n="456704.mp4" and nf="./A guide to perfect eggs" (assuming for first file). Then;



                  • With $n%.*- we are removing everything from end of fileName until first dot . seen and . itself and then added a dash -. So this will result only digits part of fileName 456704.



                  • With $fn##*/.mp4 we are removing everything from begging of fileName until last slash / seen and / itself and then added .mp4 at the end. So this will result A guide to perfect eggs.mp4.





                  1What are the security issues and race conditions in using find -exec?
                  2Why using the '-execdir' action is insecure for directory which is in the PATH?






                  share|improve this answer














                  Using find and Shell (Bash, ksh, ksh93, mksh, zsh) Pattern substitution expansion.



                  find * -type f -name "*.mp4" -exec bash -c 'echo mv -v "$1" "$1//[^0-9]-$1//[-0-9]"' _ '' ;


                  • With $1//[^0-9] we are removing everything except a number; The // is global replacement syntax while / is only for first occurrence of number.


                  • Then a dash/hyphe -, and with $1//[-0-9] we are removing everything which is a - or number (again assuming only one - and numerical part is there in files name).


                  We used -exec in above command which is not secure for some reasons1, 2 and here because with Shell Substitution Expansion it will take file's path and cause unexpected rename + it will drop all dashes - in files name!



                  At the end don't forget to remove the echo above in commands to have actual rename where it used to dry run.




                  find . -type f -name "*.mp4" -execdir sh -c '
                  n="$1##*-";fn="$1%-*";
                  echo mv -v "$1" "$n%.*-$fn##*/.mp4" ' _ '' ;


                  Same as previous command but here we used shell (POSIX sh/bash/Korn/zsh) parameter substitution expansion and this will grantee to keep all dashes - untouched within filesname if any like a file-with -- here-006.file except the last one which should be drop.



                  We are looking for the files only -type f ends with .mp4 and with -execdir here, find is changing the current directory to the directory where a file found then execute the sh -c ' ... ' within that directory itself.



                  • With n="$1##*-" "cut-up-to-last-prefix": we are removing everything from the begging of filename until last dash - seen and - itself and assign to variable n; The $1 or $1 is the relative path to ./fileName to the current directory by -execdir sh -c '...' _ '' ; returns.



                  • With fn="$1%-*" "cut-up-to-first-suffix": We are removing everything from end of filename until first dash - seen and - itself and assign to variable fn.



                    Now n="456704.mp4" and nf="./A guide to perfect eggs" (assuming for first file). Then;



                  • With $n%.*- we are removing everything from end of fileName until first dot . seen and . itself and then added a dash -. So this will result only digits part of fileName 456704.



                  • With $fn##*/.mp4 we are removing everything from begging of fileName until last slash / seen and / itself and then added .mp4 at the end. So this will result A guide to perfect eggs.mp4.





                  1What are the security issues and race conditions in using find -exec?
                  2Why using the '-execdir' action is insecure for directory which is in the PATH?







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Oct 16 '17 at 18:37

























                  answered Oct 16 '17 at 13:49









                  αғsнιη

                  15.6k92563




                  15.6k92563




















                      up vote
                      0
                      down vote













                      set "a file blah blah-004.file" 
                      "b file blah blah blah-002.file"
                      "c file blahh blah-003.file"
                      "d file blah blah blah blabby blah-001.file"
                      "e file blah-005.file"

                      for name; do
                      old=$name # save old name
                      ext=$name##*. # take extension
                      name=$name%.* # remove extension
                      number=$name##*- # take number
                      name=$name%-* # remove number
                      new="$number-$name.$ext" # set new name
                      echo mv "$old" "$new" # test rename
                      done


                      Remove the last echo, if it works.






                      share|improve this answer




















                      • What if there were hundreds of files?
                        – Î±Ò“sнιη
                        Oct 16 '17 at 17:36










                      • @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                        – ceving
                        Oct 16 '17 at 20:11











                      • You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:10










                      • Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                        – ceving
                        Oct 17 '17 at 9:16















                      up vote
                      0
                      down vote













                      set "a file blah blah-004.file" 
                      "b file blah blah blah-002.file"
                      "c file blahh blah-003.file"
                      "d file blah blah blah blabby blah-001.file"
                      "e file blah-005.file"

                      for name; do
                      old=$name # save old name
                      ext=$name##*. # take extension
                      name=$name%.* # remove extension
                      number=$name##*- # take number
                      name=$name%-* # remove number
                      new="$number-$name.$ext" # set new name
                      echo mv "$old" "$new" # test rename
                      done


                      Remove the last echo, if it works.






                      share|improve this answer




















                      • What if there were hundreds of files?
                        – Î±Ò“sнιη
                        Oct 16 '17 at 17:36










                      • @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                        – ceving
                        Oct 16 '17 at 20:11











                      • You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:10










                      • Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                        – ceving
                        Oct 17 '17 at 9:16













                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      set "a file blah blah-004.file" 
                      "b file blah blah blah-002.file"
                      "c file blahh blah-003.file"
                      "d file blah blah blah blabby blah-001.file"
                      "e file blah-005.file"

                      for name; do
                      old=$name # save old name
                      ext=$name##*. # take extension
                      name=$name%.* # remove extension
                      number=$name##*- # take number
                      name=$name%-* # remove number
                      new="$number-$name.$ext" # set new name
                      echo mv "$old" "$new" # test rename
                      done


                      Remove the last echo, if it works.






                      share|improve this answer












                      set "a file blah blah-004.file" 
                      "b file blah blah blah-002.file"
                      "c file blahh blah-003.file"
                      "d file blah blah blah blabby blah-001.file"
                      "e file blah-005.file"

                      for name; do
                      old=$name # save old name
                      ext=$name##*. # take extension
                      name=$name%.* # remove extension
                      number=$name##*- # take number
                      name=$name%-* # remove number
                      new="$number-$name.$ext" # set new name
                      echo mv "$old" "$new" # test rename
                      done


                      Remove the last echo, if it works.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Oct 16 '17 at 14:01









                      ceving

                      1,68621321




                      1,68621321











                      • What if there were hundreds of files?
                        – Î±Ò“sнιη
                        Oct 16 '17 at 17:36










                      • @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                        – ceving
                        Oct 16 '17 at 20:11











                      • You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:10










                      • Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                        – ceving
                        Oct 17 '17 at 9:16

















                      • What if there were hundreds of files?
                        – Î±Ò“sнιη
                        Oct 16 '17 at 17:36










                      • @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                        – ceving
                        Oct 16 '17 at 20:11











                      • You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:10










                      • Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                        – ceving
                        Oct 17 '17 at 9:16
















                      What if there were hundreds of files?
                      – Î±Ò“sнιη
                      Oct 16 '17 at 17:36




                      What if there were hundreds of files?
                      – Î±Ò“sнιη
                      Oct 16 '17 at 17:36












                      @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                      – ceving
                      Oct 16 '17 at 20:11





                      @αғsнιη What are you asking? How to remove the set in order to pass the names as arguments?
                      – ceving
                      Oct 16 '17 at 20:11













                      You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                      – Î±Ò“sнιη
                      Oct 17 '17 at 9:10




                      You are using set but this you will do for hundreds of files? this is not a way to add all files into the set.
                      – Î±Ò“sнιη
                      Oct 17 '17 at 9:10












                      Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                      – ceving
                      Oct 17 '17 at 9:16





                      Once again: remove the set and pass the list of names as arguments to the script. Either in the command line or by reading stdin using xargs. The use of set is just a mock-up for testing purposes.
                      – ceving
                      Oct 17 '17 at 9:16











                      up vote
                      0
                      down vote













                      Alternative find + prename (Perl rename) solution:



                      find -type f -exec prename 's/^(.+?)([^/]+)-([0-9]+)(.[^.]+)$/$1$3-$2$4/' '' ;





                      share|improve this answer


















                      • 1




                        @αғsнιη, if it's just for dashes - see my simple update
                        – RomanPerekhrest
                        Oct 16 '17 at 18:36










                      • Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                        – Î±Ò“sнιη
                        Oct 16 '17 at 18:41











                      • @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                        – RomanPerekhrest
                        Oct 16 '17 at 18:44










                      • a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:11














                      up vote
                      0
                      down vote













                      Alternative find + prename (Perl rename) solution:



                      find -type f -exec prename 's/^(.+?)([^/]+)-([0-9]+)(.[^.]+)$/$1$3-$2$4/' '' ;





                      share|improve this answer


















                      • 1




                        @αғsнιη, if it's just for dashes - see my simple update
                        – RomanPerekhrest
                        Oct 16 '17 at 18:36










                      • Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                        – Î±Ò“sнιη
                        Oct 16 '17 at 18:41











                      • @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                        – RomanPerekhrest
                        Oct 16 '17 at 18:44










                      • a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:11












                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      Alternative find + prename (Perl rename) solution:



                      find -type f -exec prename 's/^(.+?)([^/]+)-([0-9]+)(.[^.]+)$/$1$3-$2$4/' '' ;





                      share|improve this answer














                      Alternative find + prename (Perl rename) solution:



                      find -type f -exec prename 's/^(.+?)([^/]+)-([0-9]+)(.[^.]+)$/$1$3-$2$4/' '' ;






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Oct 16 '17 at 18:35

























                      answered Oct 16 '17 at 14:30









                      RomanPerekhrest

                      22.5k12145




                      22.5k12145







                      • 1




                        @αғsнιη, if it's just for dashes - see my simple update
                        – RomanPerekhrest
                        Oct 16 '17 at 18:36










                      • Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                        – Î±Ò“sнιη
                        Oct 16 '17 at 18:41











                      • @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                        – RomanPerekhrest
                        Oct 16 '17 at 18:44










                      • a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:11












                      • 1




                        @αғsнιη, if it's just for dashes - see my simple update
                        – RomanPerekhrest
                        Oct 16 '17 at 18:36










                      • Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                        – Î±Ò“sнιη
                        Oct 16 '17 at 18:41











                      • @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                        – RomanPerekhrest
                        Oct 16 '17 at 18:44










                      • a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                        – Î±Ò“sнιη
                        Oct 17 '17 at 9:11







                      1




                      1




                      @αғsнιη, if it's just for dashes - see my simple update
                      – RomanPerekhrest
                      Oct 16 '17 at 18:36




                      @αғsнιη, if it's just for dashes - see my simple update
                      – RomanPerekhrest
                      Oct 16 '17 at 18:36












                      Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                      – Î±Ò“sнιη
                      Oct 16 '17 at 18:41





                      Another problem is that, this will fail if there is subdirectory including mp4 files together with .mp4 files. I mean a directory with multiple mp4 files and a sub-directory also that it contains mp4 files as well
                      – Î±Ò“sнιη
                      Oct 16 '17 at 18:41













                      @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                      – RomanPerekhrest
                      Oct 16 '17 at 18:44




                      @αғsнιη, paraphrase your sentence, cause "subdirectory including files together with files" - sounds strange
                      – RomanPerekhrest
                      Oct 16 '17 at 18:44












                      a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                      – Î±Ò“sнιη
                      Oct 17 '17 at 9:11




                      a directory containing mp4 files and a sub-directory which that sub-directory also contains mp4 files (nested directories with mp4 files).
                      – Î±Ò“sнιη
                      Oct 17 '17 at 9:11










                      up vote
                      0
                      down vote













                      This is a portable sh implementation.



                      find . -name "*[0-9].mp4" |
                      sed "s/(.*/)(.*)-([0-9]*).mp4/'12-3.mp4' '13-2.mp4'/" |
                      xargs -p -L 1 mv -v


                      The find command is pretty straightforward: it will return only .mp4 files that contain at least one digit before the extension.



                      The sed command duplicates the filename, sorrounding each filename with single quotes, and then the second filename gets the digit part moved between the relative file path and the filename accordingly (e.g., './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').



                      The resulting list of current and new filenames are then passed to the xargs command, which will execute mv -v. The -L 1 option is needed so that xarg processes one line at a time. You can remove the -p option from this command and change the options that mv should use.



                      I tested this implementation with your file list on Ubuntu bash, sh, and Mac OS High Sierra bash and sh, placing files in different subdirectories and adding a few files that didn't qualify.






                      share|improve this answer
























                        up vote
                        0
                        down vote













                        This is a portable sh implementation.



                        find . -name "*[0-9].mp4" |
                        sed "s/(.*/)(.*)-([0-9]*).mp4/'12-3.mp4' '13-2.mp4'/" |
                        xargs -p -L 1 mv -v


                        The find command is pretty straightforward: it will return only .mp4 files that contain at least one digit before the extension.



                        The sed command duplicates the filename, sorrounding each filename with single quotes, and then the second filename gets the digit part moved between the relative file path and the filename accordingly (e.g., './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').



                        The resulting list of current and new filenames are then passed to the xargs command, which will execute mv -v. The -L 1 option is needed so that xarg processes one line at a time. You can remove the -p option from this command and change the options that mv should use.



                        I tested this implementation with your file list on Ubuntu bash, sh, and Mac OS High Sierra bash and sh, placing files in different subdirectories and adding a few files that didn't qualify.






                        share|improve this answer






















                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          This is a portable sh implementation.



                          find . -name "*[0-9].mp4" |
                          sed "s/(.*/)(.*)-([0-9]*).mp4/'12-3.mp4' '13-2.mp4'/" |
                          xargs -p -L 1 mv -v


                          The find command is pretty straightforward: it will return only .mp4 files that contain at least one digit before the extension.



                          The sed command duplicates the filename, sorrounding each filename with single quotes, and then the second filename gets the digit part moved between the relative file path and the filename accordingly (e.g., './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').



                          The resulting list of current and new filenames are then passed to the xargs command, which will execute mv -v. The -L 1 option is needed so that xarg processes one line at a time. You can remove the -p option from this command and change the options that mv should use.



                          I tested this implementation with your file list on Ubuntu bash, sh, and Mac OS High Sierra bash and sh, placing files in different subdirectories and adding a few files that didn't qualify.






                          share|improve this answer












                          This is a portable sh implementation.



                          find . -name "*[0-9].mp4" |
                          sed "s/(.*/)(.*)-([0-9]*).mp4/'12-3.mp4' '13-2.mp4'/" |
                          xargs -p -L 1 mv -v


                          The find command is pretty straightforward: it will return only .mp4 files that contain at least one digit before the extension.



                          The sed command duplicates the filename, sorrounding each filename with single quotes, and then the second filename gets the digit part moved between the relative file path and the filename accordingly (e.g., './a/Boil an egg-456707' './a/456707-Boil an egg.mp4').



                          The resulting list of current and new filenames are then passed to the xargs command, which will execute mv -v. The -L 1 option is needed so that xarg processes one line at a time. You can remove the -p option from this command and change the options that mv should use.



                          I tested this implementation with your file list on Ubuntu bash, sh, and Mac OS High Sierra bash and sh, placing files in different subdirectories and adding a few files that didn't qualify.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Oct 16 '17 at 21:22









                          cesarv

                          1777




                          1777



























                               

                              draft saved


                              draft discarded















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f398409%2frename-file-names-in-multiple-directories%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Peggy Mitchell

                              Palaiologos

                              The Forum (Inglewood, California)