Change the name of many files - regex

How can I rename many files. Remove the digits at the beginning.
I have a Mac. All the files are in the same folder.
The pattern is:
1, 2 or 3 digits - any name.php
With Regular Expression, I think it would be:
\d*-(.*).php
For example:
1-marketing.php
2-3D.php
3-without.php
I want to remove the numbers and the dash at the beginning.
In the example it would be:
marketing.php
3D.php
without.php
What I have explored two ways:
Select the files > ctrl click > rename items. This is a fantastic method to change the name of files. But I think it cannot be used in this case. If I understand, it does not support Regex. Am I right?
Terminal. I am not very familiar with terminal. I tried mv 1-marketing.php marketing.php It works for 1 file, but how can I do the same for many? I am new with the terminal. If it can be done, please explain the basic.

Open the terminal app in Mac OS X and navigate to the folder containing the .php files
cd /my/path/to-php-files/
and run the below command on the command-line.
for file in *.php; do mv -v "$file" "${file#*-}"; done
The bash parameter expansion syntax ${file#*-} removes the characters before - from the beginning, so ideally 3-number-without.php becomes number-without.php
(or) use the perl rename utility not available by default in Mac OS, you can download and install it with homebrew 🍺:
brew install rename
and do
rename -n 's/^(\d+)-(.*)/$2/' *.php
The -n is just for a dry-run to see how the files are to be renamed, remove it as
rename 's/^(\d+)-(.*)/$2/' *.php
for the actual renaming.

Related

Use sed/regex to rename a file - bash with macOS

I have a list of files that a date has been added to the end.
ex: Chorus Left Octave (consolidated) (2020_10_14 20_27_18 UTC). The files will end with .wav or .mp3
I want to leave the (consolidated) but take out the date. I have come up with the regex and tested with regexr.com. It does format the text correctly there.
The regex is: /(\([0-9]+(.*)(?=.wav|.mp3))+/g
Now, I am trying to actually rename the files. In my terminal I have cd'ed into the folder with the files. Based on other answers here I have tried:
rename -n '/(\([0-9]+(.*)(?=.wav|.mp3))+/g' *.wav|*.mp3 - using rename installed with homebrew
sed '/(\([0-9]+(.*))+/g' *.wav|*.mp3
for f in *.wav|*.mp3; do mv "$f" "${f/(\([0-9]+(.*)(?=.wav|.mp3))+/g}” done
The first two do not throw any errors, but do not do any renames (I know that the -n after rename just prints out the files that will be changed, it doesn't actually change the files)
The last one starts a bash session.
I'd rather use the rename or sed, seems simpler to me. But, what am I doing wrong?.
In plain bash:
#!/bin/bash
pat='([0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9] [0-9][0-9]_[0-9][0-9]_[0-9][0-9] UTC)'
for f in *.mp3 *.wav; do echo mv "$f" "${f/$pat}"; done
Remove the echo preceding the mv after making sure it will work as intended. You may also consider adding the -i option to the mv in order to avoid clobbering an existing file unintentionally.

rename regex not working in cygwin

I am using cygwin under windows 7.
In my directory there are files like
fort.100
fort.101
...
fort.1xx
I want to give them all an extension _v1.
When I try to achieve it using rename by
rename 's/$/_v1/' fort.*
the prompt exit with no errors and nothing happens.
I then tried
rename -e 's/$/_v1/' fort.*, an error pops up,
rename: unknown option -- e
I also tried with a different delimiter # instead of / with no luck.
Now, I thought it was due to the character _ in the expression (I am a newbie to regex), I tried escaping it by \_ with no luck either. Again a try without _, for example,
rename 's/$/v11/' fort.* - nothing happens again.
Although I achieved my goal by
for file in fort.*; do mv $file $file\_v1; done, I wonder why rename doesn't work.
What am I doing wrong here? Is it because I am on cygwin?
The manual of rename does not match your expectations.
I see no regex capability.
SYNOPSIS
rename [options] expression replacement file...
DESCRIPTION
rename will rename the specified files by replacing the first occur‐
rence of expression in their name by replacement.
OPTIONS
-v, --verbose
Give visual feedback which files where renamed, if any.
-V, --version
Display version information and exit.
-s, --symlink
Peform rename on symlink target
-h, --help
Display help text and exit.
EXAMPLES
Given the files foo1, ..., foo9, foo10, ..., foo278, the commands
rename foo foo0 foo?
rename foo foo0 foo??
will turn them into foo001, ..., foo009, foo010, ..., foo278. And
rename .htm .html *.htm
will fix the extension of your html files.
for what you want to reach the easy way is:
for i in fort*; do mv ${i} ${i}_v1 ; done
I have found a workaround.
I replaced the util-linux rename to perl rename a separate package.
This was provided from #subogero from GitHub.
All the usual rename expressions is working.

Copy all Files in a List to a Unique Directory

I am trying to take a text file that contains a list of files and copy them all to a directory. Within this directory, they will have unique directory names. An example of text file the structure can be seen below:
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000003/s01_2011_11_01/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000003/s01_2011_11_01/a_1.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000003/s02_2011_11_11/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000003/s02_2011_11_11/a_1.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s01_2009_02_13/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s02_2010_10_02/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s03_2010_10_02/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s04_2010_10_03/a_.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s04_2010_10_03/a_1.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s04_2010_10_03/a_2.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s04_2010_10_03/a_3.edf
/data/isip/data/tuh_eeg/v0.6.0/edf/001/00000005/s04_2010_10_03/a_4.edf
I need a shell command or an EMACS macro to go through this list and copy them all to unique directories within the current working directory. The unique directory will depend on the file; for example, for the first two files, the directory would be
/001/00000003/s01_2011_11_01/
I have tried doing this using an EMACS macro, but I was not able to get it to work. A shell command or EMACs macro would work.
Something as simple as:
cat list | sed "s/^.*edf\/\(.*\)\/\(.*\)$/mkdir -p root_dir\/\1 \&\& cp \0 root_dir\/\1\/\2/" | sh
If on OSX - install gnu-sed and use gsed instead of sed. Run command without | sh to see what it'll do. Make sure to tweak root_dir, of course.

Regex to add an extension to a directory full of files

I am new to regular expressions.
I have many irregularly numbered ascii files with no extension: g000554, g000556, g000558, g000561, g000563 ... g001979 etc
I would like to type a regex at the terminal (or in a short script) to add a .dat to all of these files.
So I would like to change them to become: g000554.dat, g000556.dat, g000558.dat, g000561.dat, g000563.dat ... g001979.dat etc
p.s. Sorry I should have provided more info: by terminal I meant a mac terminal and I cannot use the 'rename' command.
I think you're using a linux system. So i provide a bash solution. It works only if your files starts with g and there is no other files in that directory except the files you want to rename.
for i in g*; do mv "$i" "$i.dat"; done
The below would add .dat extension to all the files present in the current directory,
for i in *; do mv "$i" "$i.dat"; done

Copy and Rename Multiple Files with Regular Expressions in bash

I've got a file structure that looks like:
A/
2098765.1ext
2098765.2ext
2098765.3ext
2098765.4ext
12345.1ext
12345.2ext
12345.3ext
12345.4ext
B/
2056789.1ext
2056789.2ext
2056789.3ext
2056789.4ext
54321.1ext
54321.2ext
54321.3ext
54321.4ext
I need to rename all the files that begin with 20 to start with 10; i.e., I need to rename B/2022222.1ext to B/1022222.1ext
I've seen many of the other questions regarding renaming multiple files, but couldn't seem to make it work for my case. Just to see if I can figure out what I'm doing before I actually try to do the copy/renaming I've done:
for file in "*/20?????.*"; do
echo "{$file/20/10}";
done
but all I get is
{*/20?????.*/20/10}
Can someone show me how to do this?
You just have a little bit of incorrect syntax is all:
for file in */20?????.*; do mv $file ${file/20/10}; done
Remove quotes from the argument to in. Otherwise, the filename expansion does not occur.
The $ in the substitution should go before the bracket
Here is a solution which use the find command:
find . -name '20*' | while read oldname; do echo mv "$oldname" "${oldname/20/10}"; done
This command does not actually do your bidding, it only prints out what should be done. Review the output and if you are happy, remove the echo command and run it for real.
Just wanna add to Explosion Pill's answer.
On OS X though, you must say
mv "${file}" "${file_expression}"
Or the mv command does not recognize it.
Brace expansions like :
{*/20?????.*/20/10}
can't be surrounded by quotes.
Instead, try doing (with Perl rename) :
rename 's/^10/^20/' */*.ext
You can do this using the Perl tool rename from the shell prompt. (There are other tools with the same name which may or may not be able to do this, so be careful.)
If you want to do a dry run to make sure you don't clobber any files, add the -n switch to the command.
note
If you run the following command (linux)
$ file $(readlink -f $(type -p rename))
and you have a result like
.../rename: Perl script, ASCII text executable
then this seems to be the right tool =)
This seems to be the default rename command on Ubuntu.
To make it the default on Debian and derivative like Ubuntu :
sudo update-alternatives --set rename /path/to/rename
The glob behavior of * is suppressed in double quotes. Try:
for file in */20?????.*; do
echo "${file/20/10}";
done