how to rename multiple files by replacing string in file name? this string contains a "#"

https://serverfault.com/questions/70939/how-to-replace-a-text-string-in-multiple-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multiple-files-by-replacing-word-in-file-name

https://serverfault.com/questions/212153/replace-string-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-string-in-linux

These mentioned articles have all answered my question. However none of them work for me. I suspect it is because the string I am trying to replace has a # in it. Is there a special way to address this?

I have image file that had an é replaced by #U00a9 during a site migration. These look like this:

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

and I want to change it to something like this:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

UPDATE:

These examples all start with “LU00a9ucky but here are many images with different names. I am simply targeting the “#U00a9” portion of the string to replace with “safe”.

not sure how to in sed, but you can try this in a bash shell:

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

explanation:

  1. loops through all file names matching the glob (Lucky-#U00a9NBC-*.jpg)
  2. renames file using the move command(mv)
  3. uses native bash parameter substitution ${var/Pattern/Replacement} to craft the new name (“${f/#U00a9/safe}”)

More on parameter substitution (which is highly underutilized IMO): http://www.tldp.org/LDP/abs/html/parameter-substitution.html

Answered By: Gregory Patmore

This is not hard, simply make sure to escape the octothorpe (#) in the name by prepending a reverse-slash ().

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 
Answered By: DTK

To escape # from the shell, just use single quotes ('#'), double quotes ("#"), or backslash (#).

The simplest in your case would be to use the rename command (if it is available):

rename '#U00a9' safe *.jpg
Answered By: mik

To replace # by somethingelse for filenames in the current directory (not recursive) you can use the (Perl-)rename utility:

rename  's/#/somethingelse/' *

Characters like - must be escaped with a .

For your case, you would want to use

rename 's/#U00a9/safe/g' *

Note that if you only want to operate on a certain selection of files, e.g., only *.jpg, adjust the final input to match that selection:

rename 's/#U00a9/safe/g' *.jpg

To perform a test before actually changing filenames, use the -n flag:

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

For OS X, rename can be installed using homebrew: brew install rename.

Answered By: KrisWebDev

Another option is to use pyRenamer, an application made specifically for batch renaming.

It can be installed with sudo apt-get install pyrenamer

For usage details, refer to its README file on GitHub.

Answered By: Sajna T

find the list of files and then replace keyword.
below is example

find . -name '*jpg' -exec bash -c ' mv $0 ${0/#U00a9NBC/safeNBC}' {} ;
Answered By: Sujit Dhamale

The above examples were not working on my system (CentOS 5.6) so I found a (possibly more system-specific) command that works (note: need to escape ‘#’ with on command line):

rename #U00a9 safe *.jpg

[Also: I don’t have enough reputation yet to comment, so in response to Nikhil’s question regarding the use of /g in rename 's/old_string/new_string/g' (posed in the comments for another answer above):

Use the g modifier to perform a ‘global’ substitution (that is, to substitute new_string for old_string as many times as old_string occurs). This shouldn’t be necessary in my answer because the rename will be applied to all files specified with *. See https://www.computerhope.com/unix/rename.htm for a concise explanation of this and other modifiers.]

Answered By: Ezra Citron

Here’s DTK’s solution wrapped in reusable bash function:

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

Here’s how you can use it:

renameFilesRecursively /home/user/my-files apple orange
Answered By: Slava Fomin II

Actually rename has an option exactly for that called --subst or -s in short. No need to use the regex syntax.

rename -s '#U00a9' 'safe' *

If you want to replace/substitute multi occurrences, use --subst-all or -S.

BTW, I only wanted to replace a string by nothing (remove it from file name)… well we also have an option for it -d/--delete and -D/--delete-all:

rename -d '#U00a9' *
Answered By: lapin

Follow these steps

ls Lucky-#U00a9NBC*.jpg 

Will display all jpg file names with Lucky-#U00a9NBC*

rename 's/Lucky-#U00a9NBC/Lucky-safeNBC/' *.jpg

After executing this command every Lucky-#U00a9NBC replace with Lucky-safeNBC.

 ls Lucky-safeNBC*.jpg

You can see all files are renamed

Answered By: Kalana

I’d say more likely #U00a9 is intended to be standing for the character U+00A9 here (©).

If you wanted to turn it back to ©, encoded in the locale’s charset, you could do with the perl variants of rename (sometimes called prename):

rename '
  use Encode::Locale;
  use Encode;
  s/#U([0-9a-f]{4})/chr hex $1/gie;
  $_ = encode(locale_fs => $_)' ./*'#'[uU]*
Answered By: Stéphane Chazelas

If you are on windows using cygwin, then what works is:

find . -type f -exec rename PhraseToReplace PlaceToReplaceWith {} ;
Answered By: Antoni Papiewski
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.