4

Please be patient, this post will be somewhat long...

I have a bunch of files, some of them with a simple and clean name (e.g. 1E01.txt) and some with a lot of extras:

Sample2_Name_E01_-co_032.txt
Sample2_Name_E02_-co_035.txt
...
Sample12_Name_E01_-co_061.txt

and so on. What is important here is the number after "Sample" and the letter+number after "Name" - the rest is disposable. If i get rid of the non-important parts, the filename reduces to the same pattern as the "clean" filenames (2E01.txt, 2E02.txt, ..., 12E01.txt). I've managed to rename the files with the following expression (came up with this one myself, don't know if is very elegant but works fine):

rename -v 's/Sample([0-9]+)_Name_([A-Z][0-9]+).*/$1$2\.txt/' *.txt

Now, the second part, is adding a leading zero for filenames with just one digit, such as 1E01.txt turns into 01E01.txt. I've managed to to this with (found and modified this on another StackExchange post):

rename -v 'unless (/^[0-9]{2}.*\.txt/) {s/^([0-9]{1}.*\.txt)$/0$1/;s/0*([0-9]{2}\..*)/$1/}' *.txt

So I finally got to my question: is there a way to merge both expressions in just one rename command? I know I could do a bash script to automate the process, but what I want is to find a one-pass renaming solution.

thanks

h.mon
  • 248
  • 2
  • 10
  • I don't see why you would want a one-pass solution for two essentially different operations. If you want, you could put both commands on the same line. – Tim Nov 06 '12 at 12:09
  • Just searching for elegance. And they are not different operations, both are renaming the same files. – h.mon Nov 06 '12 at 12:12
  • @Tim N: Afterthought: you are right, as I have two types of names to begin with, I think I need both expressions. – h.mon Nov 06 '12 at 12:15
  • possible duplicate of [linux shell script to add leading zeros to file names](http://stackoverflow.com/questions/3672301/linux-shell-script-to-add-leading-zeros-to-file-names) – Serge Stroobandt Mar 04 '14 at 20:27

2 Answers2

12

You can try this command to rename 1-file.txt to 0001-file.txt

# fill zeros
$ rename 's/\d+/sprintf("%04d",$&)/e' *.txt

You can change the command a little to meet your need.

kev
  • 155,172
  • 47
  • 273
  • 272
1

Well if that is your "parsing" regex, then you are limiting the files that the script can act on those matching that pattern. Thus, the sprintf using the same literal strings is not a more specialized case, and you could just do this:

s{Sample(\d+)_Name_(\p{IsUpper})(\d+)}
 {sprintf "Sample%02d_Name_%s%03d", $1, $2, $3}e
 ;

Here, you are using the same known features again and simply formatting the accompanying numbers.

  • The /e switch is for 'eval' and it evaluates the replacement as Perl for each match.
  • I renamed some of your expressions to more standard character class symbols: [A-Z] becomes the property class \p{IsUpper}, [0-9] becomes the digit code \d (also possible \p{IsDigit} ).
Axeman
  • 29,660
  • 2
  • 47
  • 102