1

I have a bunch of files that I'd like to rename. Their filenames are in a certain format:

p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j

There's a prefix before each unique file name. In this case, that prefix starts with the letter p and has a number after the p that increments by one. A period (.) separates the prefix from the unique file name. There's a suffix after each unique file name that begins with a hashtag (#). I'd like to remove the prefixes up to and including the periods and I'd also like to remove the suffixes beginning at and including the hashtags. I'd like the resulting filenames to be only the unique file names between the periods and the hash tags like this:

uniquenameA
uniquenameB
uniquenameC
uniquenameD
uniquenameE
uniquenameF
uniquenameG
uniquenameH
uniquenameI
uniquenameJ

I'm new to scripting, so if you could explain how the code works in addition to supplying the code, I'd greatly appreciate it.

  • 1
    Hello user10200596. Generally, we're not a script-writing service, and we prefer people to show what they have tried so that we can help them improve it. – roaima May 29 at 22:14
  • My apologies for not being able to provide any code. Because I'm new to this, I didn't really know what to try. Thank you, though, for your response! – Data2Dollars May 30 at 20:56
2

If you've got the perl version of rename (sometimes formerly called prename) you can apply a Regular Expression substitution:

rename -n 's/^.*?\.(.*?)#.*/$1/' *

If you don't understand Regular Expressions (REs) they're very much worth learning.

  • s/xx/yy/ - replace xx with yy
  • ^ - match an implicit start-of-line
  • .*? - match as short a string as possible of zero or more characters of anything subject to the rest of the pattern matching
  • \. - match a literal dot . (the . character represents anything, but \. is a literal dot)
  • (...) match a pattern inside the brackets and assign it a match number 1..9; later referenced by $1 (the second (...) would be $2, etc.)
  • # - literal character
  • .* - the longest match that is zero or more characters of anything (the . is anything and the * means _zero or more of the preceding item)

Remove the -n ("no action") when you are happy it would work. Replace it with -v to see what's actually happening, or just omit it for silent operation.

  • I'm working in Mac OSX's Terminal, which does not haverename, unfortunately. Is there a way to install it? Thanks. – Data2Dollars May 30 at 20:57
  • @user10200596 I'm sorry, I don't know. Something called brew may have it?? (I wouldn't have suggested it if you'd indicated you were using a Mac. For next time, the relevant tag is osx.) – roaima May 30 at 21:55
0

Here is an awk script that does the task:

Only for printing/debug:

awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){print "mv "$0" "m[2] }' input.txt    

Do the rename:

awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){system("mv "$0" "m[2])}' input.txt    

input.txt

p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j

output

mv p1.uniquenameA#blah_a uniquenameA
mv p2.uniquenameB#blah_b uniquenameB
mv p3.uniquenameC#blah_c uniquenameC
mv p4.uniquenameD#blah_d uniquenameD
mv p5.uniquenameE#blah_e uniquenameE
mv p6.uniquenameF#blah_f uniquenameF
mv p7.uniquenameG#blah_g uniquenameG
mv p8.uniquenameH#blah_h uniquenameH
mv p9.uniquenameI#blah_i uniquenameI
mv p10.uniquenameJ#blah_j uniquenameJ
-1

Here is a solution using sed

for i in *
do
    mv $i $( echo $i | sed 's/p[[:digit:]]*\.\([^#]*\)\#.*/\1/' )
done

The destination is created by using sed by looking for a p followed by any number of digits followed by a period. The characters from the period onwards up to the # character are remembered into a register, and the entire filename is substituted by the remembered characters.

  • And the explanation, as requested in the question...? – roaima May 29 at 22:59
  • This worked. Thanks! I will definitely work on getting the regular expressions down. I really appreciate your help! – Data2Dollars May 30 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.