Renaming multiple files

I have 34 file in a directory that all have different names, however, they do have 1 pattern in commmon. They all have "-10-11-2010" date format in the name. I want to replace the date in the file name with a supplied date or maybe even the system date. I am sure I will be using awk or sed to accomplish this. Any help would be great. Thanks in advance.

P.S.
Any ideas why the .bash_profile will not load or be read at login time? I set one up for a user and they have to issue the source command in order for their .bash_profile to take affect. The default .profile is normal and everyone uses it, in fact not many use .bash_profile or a custom .profile

Thanks!

Hi.

To your first question:

NEW="12-12-2012" # get this value whichever way

ls *-10-11-2010* | while read FILE; do
  mv "$FILE" "${FILE/-10-11-2010/-$NEW}"
done

Or in sed / xargs (no good if the filenames have spaces):

NEW="12-12-2012"

ls *-10-11-2010* | sed "p; s/-10-11-2010/-$NEW/" | xargs -n2 mv

Awesome. I will give it a shot. Thanks!!!!!

---------- Post updated at 08:38 PM ---------- Previous update was at 08:31 PM ----------

The only issue is, is that the dates in the filename may all be different. Some may say text-09-20-2008-text or text-10-10-2007-text. I was thinking i could just match for numbers, any numbers in the format text-00-00-0000-text and replace what ever number are text-num-num-num-text to the date of my choice. Are there some gen expressions i could use, or some perl one liners?

#!/bin/bash
newdate=00-00-0000
for file in *[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]*
do
echo mv $file ${file%[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9].*}$newdate${file#*[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]}
done

Wow! thats crazy. I will try it and let you know. Thanks for the help.

Hi,

Another solution:

find . -type d | sed 's/\(.*\/.*\)[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}\(.*\)/mv & \1$(date +%m-%d-%Y)\2/' | sh -x

Regards,

find . -type d | sed "s/\(.*\/.*\)[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}\(.*\)/mv & \1$(date +%m-%d-%Y)\2/" | sh -x

Hi danmero,

Could you explain me the difference, please?

I run both commands in my shell and the result is the same. I know the shell interpretation of both types of quotes, but not in this case.

Thank you.

# find . -type d | sed 's/\(.*\/.*\)[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}\(.*\)/mv & \1$(date +%m-%d-%Y)\2/'
.
mv ./test-01-01-2010-directory ./test-$(date +%m-%d-%Y)-directory

# find . -type d | sed "s/\(.*\/.*\)[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\}\(.*\)/mv & \1$(date +%m-%d-%Y)\2/"
.
mv ./test-01-01-2010-directory ./test-10-12-2010-directory

Quote from: The Open Group Base Specifications Issue 6

They both give the same result because they both perform the same command substitution and the substituted text does not contain any sh metacharacters.. The only difference is which sh instance handles it. In the original version, the sh subshell at the end of the pipeline will handle it. In danmero's, the sh parsing the pipeline handles it.

While I am not a fan of this solution's approach (it fails if a filename that does not match the sed pattern is present, if a matching filename contains a shell metacharacter, whitespace/IFS characters), if i had to choose one I'd go with the original version because it presents better "compartmentalization"; command execution, both mv and the date command substitution are handled by the same sh.

That said, I prefer danmero's for loop approach best of all. If the parameter expansions were quoted, it'd be bulletproofed against all legal filenames. With all the other approaches, this is not possible. Also, despite the "/bin/bash", it should work fine in any posix-compliant shell.

Regards,
Alister

1 Like