We are going to use rename which is a perl script, and also the know mv, together with for, in "one-line" shell-script
rename
Syntax
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
- -v
- Verbose: print names of files successfully renamed.
- -n
- No Action: show what files would have been renamed.
- -f
- Force: overwrite existing files.
- perlexpr Perl Expression
Regular Expressions
^
- matches the beginning of the line
$
- matches the end of the line
.
- Matches any single character
(character)*
- match arbitrarily many occurences of (character)
(character)?
- Match 0 or 1 instance of (character)
[abcdef]
- Match any character enclosed in [] (in this instance, a b c d e or f)
ranges of characters such as[a-z]
are permitted. The behaviour
of this deserves more description. See the page on grep
for more details about the syntax of lists. [^abcdef]
- Match any character NOT enclosed in [] (in this instance, any character other than a b c d e or f)
(character)\{m,n\}
- Match m-n repetitions of (character)
(character)\{m,\}
- Match m or more repetitions of (character)
(character)\{,n\}
- Match n or less (possibly 0) repetitions of (character)
(character)\{n\}
- Match exactly n repetitions of (character)
\(expression\)
- Group operator.
\n
- Backreference - matches nth group
expression1\|expression2
- Matches expression1 or expression 2. Works with GNU sed, but this feature might not work with other forms of sed.
\w
- matches any single character classified as a “word” character (alphanumeric or “_”)
\W
- matches any non-“word” character
\s
- matches any whitespace character (space, tab, newline)
\S
- matches any non-whitespace character
\d
- matches any digit character, equiv. to [0-9]
\D
- matches any non-digit character
As rename is a perl cript you will need perl to run it, and here are some examples about how to use it.
$ rename -v 's/\.htm$/\.html/' *.htm
This is going to change htm to html in every file ending with .htm in its name.
If you want to change the name of something like this:
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 19:33 1.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 19:33 2.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 19:34 3.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-28 20:35 b.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-28 20:35 c.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-28 20:35 d.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-28 20:35 e.txt
That is the output of ls -l
, and are files created with touch
by me for this examples.
nNow lets say I want to add a more descriptive string to the name of these files like Thesis, so here we go.
rename -n 's/(\w{1})\.txt$/$1_thesis\.txt/' *.txt
Note: I am using -n to make only a test and see if the result is what I want
1.txt renamed as 1_thesis.txt
2.txt renamed as 2_thesis.txt
3.txt renamed as 3_thesis.txt
b.txt renamed as b_thesis.txt
c.txt renamed as c_thesis.txt
d.txt renamed as d_thesis.txt
e.txt renamed as e_thesis.txt
As you see that is what I wanted, now lets suppose I only want to change the name to files with a number in the name and with a letter in it.
rename -n 's/(\d{1})\.txt$/$1_thesis\.txt/' *.txt
1.txt renamed as 1_thesis.txt
2.txt renamed as 2_thesis.txt
3.txt renamed as 3_thesis.txt
You can also match only the ones with non-digit names
rename -n 's/(\D{1})\.txt$/$1_thesis\.txt/' *.txt
And the output will be:
b.txt renamed as b_thesis.txt
c.txt renamed as c_thesis.txt
d.txt renamed as d_thesis.txt
e.txt renamed as e_thesis.txt
As you may see, it is just a "using the right regexp" thing.
In case you do not have rename on your system (I think non-Debian does not have) you can use mv
Using mv
Introduction
Here we will first need to learn something about bash string operators
Match and substitute, there are two basic forms for this, substitute from the right of the match and from the left of the match.
substitution from the right
${var%t*string}
Now if we want to erase the word thesis from the previous example just enter:
for i in *.txt; do mv "$i" "${i%t*.txt}.txt"; done
Before:
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 1_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 2_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 3_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 b_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 c_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 d_thesis.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 e_thesis.txt
After:
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 1_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 2_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 3_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 b_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 c_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 d_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:24 e_.txt
substitution from the left
${var#string}
And if we want to replace .txt for .txt.bak just enter:
Now lets suppose we have this:
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-1_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-2_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-3_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-b_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-c_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 thesis-e_.txt
And we want to erase the word thesis
Just enter this:
for f in thesis*; do mv "$f" "${f#thesis-}"; done
And the output of ls -l
will now be:
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 1_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 2_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 3_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 b_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 c_.txt
-rw-r--r-- 1 ggarron ggarron 0 2007-12-30 20:28 e_.txt
My example :
I have a lot of files named Untitled-xxx.jpg. Now I want to rename to xxx.jpg
I must use the syntaxe : rename 's/^Untitled-//g ; s/^0+//g' *.jpg
No comments:
Post a Comment