1

I have thousands of files that I need to rename. They all contain a 10 digit number that all begin with '42469'. I need to move this 10 digit in each of the files to the beginning of the filename and add an underscore. Example:

Original - HOLZHEAUSER GAS UNIT_ 2_4246932863_2.pdf
Result -   4246932863_HOLZHEAUSER GAS UNIT_2_2.PDF

Can anyone help me with this? Thank you in advance!

I am not a real experienced script user/programmer, so my choice would be to be able to do this in Powershell. I have tried the two suggestions in Powershell without any luck.

Amy
  • 11
  • 2
  • 2
    Your example also shows a space being removed, and the case of the extension being changed - are these also requirements? – steeldriver Feb 25 '20 at 16:41
  • 1
    1) Would the standard text processing tools (grp, sed, awk, et al.) of Linux be suitable, or must Powershell be used? 2) Which version of Linux have you installed  (Ubuntu server, Ubuntu desktop, Kubuntu, Lubuntu, Xubuntu, Ubuntu MATE, et al.) , and which release number? Please click [edit] and add that useful information to your question so all the facts we need are in the question. Please do not use Add Comment. – K7AAY Feb 25 '20 at 16:59

3 Answers3

2

Using mmv to rename files with wildcard matching:

$ touch 'HOLZHEAUSER GAS UNIT_ 2_4246932863_2.pdf'
$ mmv '*_ ?_*_?.*' '#3_#1_#2_#4.#u5'
$ ls
'4246932863_HOLZHEAUSER GAS UNIT_2_2.PDF'
  • Adding a _for..next_ control structure to perform this for every matching file would complete the OP request. – K7AAY Feb 25 '20 at 22:10
  • @K7AAY `mmv` will apply the transformation to each matching file in the current directory - no need for a loop – steeldriver Feb 26 '20 at 02:32
0

You can use perl rename tool:

rename -n 's/(.*?)(\d{10}_)(.*?)/$2$1$3/' *

s/pattern/replacement/ means substitution of text that matches the pattern with the given replacement. Text, that matches the patterns inside the brackets are saved and can be backreferenced in the desired order in the replacement string with $1, $2 and $3 respectively.

Note, -n means: No action: print names of files to be renamed, but don't rename. Remove the -n to run the operation only if your happy with the result.

pLumo
  • 26,204
  • 2
  • 57
  • 87
-1

You can also do it with sed. This command should exactly do what you want:

ls | sed -r 's/(.*) 2_(42469)([0-9]+)_2(.*)/"&" "\2\3_\12_2\4"/' | xargs -L1 mv -v
Jonas
  • 544
  • 2
  • 7
  • [Do not parse ls](https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead). – pLumo Mar 02 '20 at 16:28
  • Ok, I guess I see your point. However, as long as there is no newline in his filenames this command will work as expected. I think a line termination in a file name shouldn't occur that often. Working over 10 years in linux I didn't even knew about that being possible. Actually I have never seen it before. – Jonas Mar 03 '20 at 09:05