I have hundred of file name with a number tag in filename like this:


and i want to rename so:

#012 - AAAA #12 SSSS.TXT
#231 - BBB #231 CDF.TXT

How I can do it?


  • Is the "number tag" always the 2nd space-separated portion of the filename, and always following a #-mark? – Jeff Schaller Feb 1 '19 at 18:37
  • no, I am unlucky... maybe the second, the third or more but is ever in the pattern #000 one #, 1 or more number and a space... – Ancucchi Feb 1 '19 at 18:38
  • but it's always some digits following a # mark? – Jeff Schaller Feb 1 '19 at 18:39
  • 2
    (probably) my last question: do you have to use find here, because they're all in various subdirectories, or are they all in the same directory? – Jeff Schaller Feb 1 '19 at 18:42
  • 1
    they are all in the same folder and the # appear one time in every filename... – Ancucchi Feb 1 '19 at 18:43

In the bash shell,

for file in *.TXT
  [[ $file =~ \#([[:digit:]]+) ]] && mv -- "$file" "#$(printf '%03d' "${BASH_REMATCH[1]}") - ${file}"

This loops over all of the files in the current directory that end in .TXT and compares them with bash's =~ conditional expression operator. It compares the incoming filename to the regular expression on the right. The regex looks for a hash mark (escaped, so it's not a comment), followed by some (captured in parenthesis) digits. The + is greedy, so it will pick up as much of the number as it can (1 digit, 4 digits, etc), ending at the first non-digit (space, in your case).

Bash saves the captured number in ${BASH_REMATCH[1]} (since it was the first set of parenthesis); we send that number to printf in order to get it zero-padded to three digits, then append on the - for the rest of the rename.

The rename only happens if the match was successful (via the && chaining).

| improve this answer | |
  • 1
    I strongly recommend using mv -i or -n when doing any sort of bulk rename like this, to avoid silently & irreversibly deleting files in case of a name conflict. – Gordon Davisson Feb 1 '19 at 18:56
  • absolutely; additional options are to run it on some test files, and/or prepend the mv with an echo (though you'd have to look carefully to know where the filenames start and end) – Jeff Schaller Feb 1 '19 at 18:59
  • IT WORKS PERFECTLY!!! – Ancucchi Feb 1 '19 at 19:08

If you have the Perl-based rename command

$ rename -n 's/.*#(\d+).*/sprintf "#%03d - %s", $1, $&/e' *.TXT
rename(AAAA #12 SSSS.TXT, #012 - AAAA #12 SSSS.TXT)
rename(BBB #231 CDF.TXT, #231 - BBB #231 CDF.TXT)

(-n added for testing purposes).

| improve this answer | |

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.