Let's analyze your sed commands:

First sed command

sed -E 's/^(.*)$/^S01E(.*)$/g'

The substitution-regex captures everything from beginning ^ to end $ of line, using (.*). Normally sed would require you to escape the parentheses: \(.*\), but since you're using -E it's correct as printed. Next, it attempts to prefix the captured content with S01E. This where it goes wrong: The regex patterns ^ (.*) $ should not be repeated in the replacement. Instead, just put your prefix, followed by \1 which represents the first capture group (parentheses). A second capture would end up in \2 and so forth. And oh, the g modifier is not needed since there will only be a single replacement. So:

test1=`echo /S01E\\1/'`

result for file 01-somemovie.mkv:

S01E01-somemovie.mkv

Second sed command

sed 's#^(.*)$#^S01E(.*)$#' 

has a similar problem in the replacement part, plus you should escape the parentheses since it doesn't use -E. Do like this:

sed 's#^\(.*\)$#S01E\1#'

Pro tip

Since you are on Mac OSX, use Homebrew to install the utility rename. Then just rename --prepend S01E *.mkv and you're done:

$ brew install rename
$ rename -n --prepend S01E *.mkv
'01-somemovie.mkv' would be renamed to 'S01E01-somemovie.mkv'
'02-somemovie.mkv' would be renamed to 'S01E02-somemovie.mkv'
Answer from grebneke on Stack Overflow
🌐
Apple Community
discussions.apple.com › thread › 5223529
Rename files in Terminal using mv and sed - Apple Community
August 7, 2013 - I wanted "rename IMG_0205.jpg to HVAC_0205.jpg". The arguments to mv seem to be reversed, so the mv command can't "rename" (or delete) the HVAC* file before it is created. ... To check before execution to make sure the output is correct, you can pipe it to a text file before terminal actually executes:
Discussions

sed - how to rename multiple files by replacing string in file name? this string contains a "#" - Unix & Linux Stack Exchange
getting: new target ....... is not a directory for each file it tries to process. ... 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): ... Thanks. While the highest voted answer (rename 's/#/somethingelse/' *) didn't work on my machine ... More on unix.stackexchange.com
🌐 unix.stackexchange.com
How to rename multiple files with sed?
Don't need sed, use bash. for i in *-tmp ; do mv "${i}" "${i/-tmp/.tmp}" ; done More on reddit.com
🌐 r/bash
14
6
March 18, 2022
macos - How to rename files using Zsh shell and `sed` command on Mac OSX - Stack Overflow
I have a folder on my desktop called "Images", inside that folder are 3 images... ... ...I want to rename the files on the command line so the second hyphen/dash is removed. So the result would be files named like so... ... ...I'm using a combination of commands piped through to each other but not having much luck in getting them to work. Initially I had ls File-* | sed ... More on stackoverflow.com
🌐 stackoverflow.com
bash - How to Batch Rename Files in a macOS Terminal? - Stack Overflow
I have a folder with a series of files named: prefix_1234_567.png prefix_abcd_efg.png I'd like to batch remove one underscore and the middle content so the output would be: prefix_567.png prefix_... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 13
182

First, I should say that the easiest way to do this is to use the prename or rename commands.

On Ubuntu, OSX (Homebrew package rename, MacPorts package p5-file-rename), or other systems with perl rename (prename):

Copyrename s/0000/000/ F0000*

or on systems with rename from util-linux-ng, such as RHEL:

Copyrename 0000 000 F0000*

That's a lot more understandable than the equivalent sed command.

But as for understanding the sed command, the sed manpage is helpful. If you run man sed and search for & (using the / command to search), you'll find it's a special character in s/foo/bar/ replacements.

Copy  s/regexp/replacement/
         Attempt  to match regexp against the pattern space.  If success‐
         ful,  replace  that  portion  matched  with  replacement.    The
         replacement may contain the special character & to refer to that
         portion of the pattern space  which  matched,  and  the  special
         escapes  \1  through  \9  to refer to the corresponding matching
         sub-expressions in the regexp.

Therefore, \(.\) matches the first character, which can be referenced by \1. Then . matches the next character, which is always 0. Then \(.*\) matches the rest of the filename, which can be referenced by \2.

The replacement string puts it all together using & (the original filename) and \1\2 which is every part of the filename except the 2nd character, which was a 0.

This is a pretty cryptic way to do this, IMHO. If for some reason the rename command was not available and you wanted to use sed to do the rename (or perhaps you were doing something too complex for rename?), being more explicit in your regex would make it much more readable. Perhaps something like:

Copyls F00001-0708-*|sed 's/F0000\(.*\)/mv & F000\1/' | sh

Being able to see what's actually changing in the s/search/replacement/ makes it much more readable. Also it won't keep sucking characters out of your filename if you accidentally run it twice or something.

2 of 13
61

You've had your sed explanation. Now you can use just the shell. No need for external commands.

Copyfor file in F0000*
do
    echo mv "$file" "${file/#F0000/F000}"
    # ${file/#F0000/F000} means replace the pattern that starts at beginning of string
done

Note that this snippet runs echo as a safety measure that prints what the mv command will do without doing it. To actually perform the mv, you need to remove echo.

🌐
Reddit
reddit.com › r/bash › how to rename multiple files with sed?
r/bash on Reddit: How to rename multiple files with sed?
March 18, 2022 -
  1. Sample files as follow; I just want to rename -tmp to .tmp

$ ls -1 *tmp
file-3-tmp
file-4-tmp

2. 1st attempt with sed

$ for i in *tmp; do echo $i | sed 's/-t/.t/'; done
file-3.tmp
file-4.tmp

Looks promising, but this is just echo, not the actual file. Same output as step 1. So I use sed -i but still didn't work

$ for i in *tmp; do sed -i 's/-t/.t/' $i; done
$ ls -1 *tmp
file-3-tmp
file-4-tmp

Let me know the right way to do this. Thanks

Top answer
1 of 9
281

In your specific case you can use the following bash command (bash is the default shell on macOS):

for f in *.png; do echo mv "$f" "${f/_*_/_}"; done

Note: If there's a chance that your filenames start with -, place -- before them[1]:
mv -- "$f" "${f/_*_/_}"

Note: echo is prepended to mv so as to perform a dry run. Remove it to perform actual renaming.

You can run it from the command line or use it in a script.

  • "${f/_*_/_}" is an application of bash parameter expansion: the (first) substring matching pattern _*_ is replaced with literal _, effectively cutting the middle token from the name.
  • Note that _*_ is a pattern (a wildcard expression, as also used for globbing), not a regular expression (to learn about patterns, run man bash and search for Pattern Matching).

If you find yourself batch-renaming files frequently, consider installing a specialized tool such as the Perl-based rename utility. On macOS you can install it using popular package manager Homebrew as follows:

brew install rename

Here's the equivalent of the command at the top using rename:

rename -n -e 's/_.*_/_/'  *.png

Again, this command performs a dry run; remove -n to perform actual renaming.

  • Similar to the bash solution, s/.../.../ performs text substitution, but - unlike in bash - true regular expressions are used.

[1] The purpose of special argument --, which is supported by most utilities, is to signal that subsequent arguments should be treated as operands (values), even if they look like options due to starting with -, as Jacob C. notes.

2 of 9
129

To rename files, you can use the rename utility:

brew install rename

For example, to change a search string in all filenames in current directory:

rename -nvs searchword replaceword *

Remove the 'n' parameter to apply the changes.

More info: man rename

Find elsewhere
🌐
Super User
superuser.com › questions › 1467293 › rename-files-with-sed-rearanging-filenames
bash - rename files with sed (rearanging filenames) - Super User
funny story - I have openSUSE and this command is not working with latest rename version..., probably it's a good answer but how to make it work (I assume that sed will be used) ... Make sure it's the right rename. man rename should give Larry Wall as the AUTHOR. Otherwise try prename or perl-rename. ... Do cd into the folder holding the files.
Top answer
1 of 2
2

There are a few issues here. First of all, your files are not in /00101234/, / is the root directory, kinda like Windows's C:. Your files are in ~/Desktop/images/00101234/ which means /home/yourUserName/Desktop/images/ (where yourUserName is your user name). The easiest way to deal with this, therefore, is to use relative paths. For example, consider this file:

/dir1/dir2/file

That's the absolute path to file. But if you are inside the dir1 directory, you can use a path that's relative to your current location: dir2/file.

With this in mind, let's have another look at your csv file:

/00101234/1101.jpg,/Jewellery/ALittleThankYouTeacher1101.jpg

These are relative paths. You can deal with this in two ways:

  1. Move into the ~/Desktop/images directory and use the paths as they are.
  2. Convert them to absolute paths.

I will focus on 2 since it is less likely to break. This command will not actually do anything, but it will print out the list of actions to be performed (run this from the directory containing your csv file and change yourCsv.csv to the actual name of your file):

while IFS=, read -r old new; do
    echo mv "~/Desktop/images${old}" "~/Desktop/images/Jewlery${new}"
done < yourCsv.csv

On my system, using the file you provided, this prints:

mv ~/Desktop/images/00101234/1101.jpg ~/Desktop/images/Jewlery/Jewellery/ALittleThankYouTeacher1101.jpg
mv ~/Desktop/images/00101234/1102.jpg ~/Desktop/images/Jewlery/Jewellery/ALittleThinkingOfYou1102.jpg
mv ~/Desktop/images/00101234/1155.jpg ~/Desktop/images/Jewlery/Jewellery/ALittleDreamcatcher1155.jpg
mv ~/Desktop/images/00101234/1203.jpg ~/Desktop/images/Jewlery/Jewellery/ALittleLuckyElephant1203.jpg

If that prints what you want, then we're ready to go. Remove the echo (that just means "print this", so removing it will cause the loop to execute the mv command instead of just printing it).

However, and this is important, your csv is probably a bit different. I am assuming you created it in Windows, which means it will have different line endings. So, to be on the safe side, you want to run this:

tr -d '\r' < yourCsv.csv | while IFS=, read -r old new; do
    mv "~/Desktop/images${old}" "~/Desktop/images/Jewlery${new}"
done < yourCsv.csv

Of course, I strongly recommend that you first make a backup of all of these files just in case something goes wrong.

2 of 2
0

This is an XY-problem, and at the moment the solution to problem X is not clear, but the solution to problem Y is:

To prevent read interpreting backslashes, use option -r. From help read:

-r        do not allow backslashes to escape any characters

Example

Setup:

$ echo '\00101191\XYZ123.jpg,\Homeware\TravelMugXYZ123.jpg' > files.csv

Without -r:

$ while IFS=, read orig new; do echo "$orig" "$new"; done < files.csv
00101191XYZ123.jpg HomewareTravelMugXYZ123.jpg

With -r:

$ while IFS=, read -r orig new; do echo "$orig" "$new"; done < files.csv
\00101191\XYZ123.jpg \Homeware\TravelMugXYZ123.jpg
🌐
Commandlinefu
commandlinefu.com › commands › view › 8368 › bulk-rename-files-with-sed-one-liner
bulk rename files with sed, one-liner Using ls, sed, xargs
April 30, 2011 - ls * | sed -e 'p;s/foo/bar/' | xargs -n2 mv - (bulk rename files with sed, one-liner Renames all files in a directory named foo to bar. foobar1 gets renamed to barbar1 barfoo2 gets renamed to barbar2 fooobarfoo gets renamed to barobarfoo NOTE: Will break for files with spaces AND new lines AND for an empty expansion of the glob '*'). The best command line collection on the internet, submit yours and save your favorites.
🌐
Reddit
reddit.com › r/macos › how can i rename bunch of files by deleting "[number]"??
r/MacOS on Reddit: How can I rename bunch of files by deleting "[number]"??
February 10, 2023 - . In short what I’m trying to do here is find any files in the current directory that contain a [, then use mv and sed to rename the files. The regex searches each filename for a string starting with [ and ending with ], and replaces that ...
🌐
Scriptthe
scriptthe.net › 2011 › 02 › 03 › using-sed-to-mass-change-folder-or-file-names
Using sed to mass change folder or file names · ./scriptthe.net
#!/bin/bash ls | grep ‘ ’ | while read file do mv “$file” echo $file | sed 's/ /./g' done #this replaces all spaces on all dir’s (or files) in the current dir with a period. Basically, this scans through every file it finds with a space and replaces it with a . Also, I had a lot of files that have a “(year)” format. I hate ( and ) because they also are a pain in the butt in linux.
🌐
GitHub
gist.github.com › harttle › ef181c81bdc5e579485614d0d82389e9
rename files with sed · GitHub
Save harttle/ef181c81bdc5e579485614d0d82389e9 to your computer and use it in GitHub Desktop. Download ZIP · rename files with sed · Raw · fsed · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below.