2
I would like to batch rename files (*.txt) by inserting a number of the format 'RXR1234567' (RXR+7digits) [if such number (and ideally only one) is found in the text] at the front of the filename, e.g. instead of
letter_235.txt
the file should be called
RXR1234567_letter_235.txt
Could this be done from the command line (grep, rename)? The files are in various subdirectories.
Your thoughts will be appreciated (as always).
I'm a bit apprehensive to do the mv right away... I've done PATTERN='RXR[0-9]{7}' but would like to first see what happens:
grep $PATTERN *.txt
is OK, but:
grep $PATTERN *.txt -exec sh -c 'grep $PATTERN "$0$"' {} ;
just produces lines like '<filename>:0' – ajo – 2010-10-02T21:52:12.287
... typo above: I DID do "$0" and not "$0$" – ajo – 2010-10-02T21:58:15.883
I thought that
PATTERN
was known before as plain text and not as regex. I've edited the answer, now it should do what you want (see the note). Anyway you can test the effects of that command by substitutingmv ...
withecho mv ..
and removing> /dev/null
. If something is unclear just ask! – cYrus – 2010-10-03T00:51:21.377find -name '.txt' -exec sh -c 'PREFIX=
grep -m 1 -oe "RXR[0-9]\{7\}" "$0"
&& echo ${PREFIX}' {} ; - this makes me see all the RXR results (I'm impressed!); I'll try the rest in a minute – ajo – 2010-10-03T02:45:33.883unfortunately, the second part doesn't seem to work?! (the files seem unchanged). What does ${0%/} mean (?directory), and ${0##/} (?filename)? - Actually, the subdirectories are not essential, if I could get it working in a single directory that would already be great... – ajo – 2010-10-03T02:51:32.220
No, actually it did work (for a number of files, but due to them starting with RXR... they were all in the middle of the list....). [I did the command twice now, those files have now ended up with RXR1234567_RXR1234567_letter125.txt, but I hope I can get that sorted with rename...) I'd still be interested in the meaning of "{0%/}" and "${0##/}", if you've got some time to explain that... And of course the fact that you've done the job with the command line, is simply amazing - Thank you for your help. – ajo – 2010-10-03T03:05:29.513
@ajo:
{0%/*}
does the same thing asdirname
(outputs the directory without the filename) and${0##*/}
does the same thing asbasename
(outputs the filename without the directory). – Paused until further notice. – 2010-10-03T07:04:36.693@Dennis Williamson: Thank you Dennis that way is more readable. – cYrus – 2010-10-03T11:24:01.167
@ajo: Dennis already show you the meaning of them. If you want more info take a look at
man bash
, sectionParameter Expansion
. – cYrus – 2010-10-03T11:28:46.490how would I write the argument for 'dirname' in the above?? – ajo – 2010-10-05T06:11:46.130
Does this look okay? find -name '*.txt' -exec sh -c 'PREFIX=$(grep -m 1 -oe "[Rr][Xx][Rr][0-9]{7}" "$0") && mv "$0" "$(dirname {})/$(basename {})"' ; – ajo – 2010-10-05T07:19:45.380
Not exactly: find -name '*.txt' -exec sh -c 'PREFIX=$(grep -m 1 -oe "[Rr][Xx][Rr][0-9]{7}" "$0") && mv "$0" "$(dirname $0)/${PREFIX}_$(basename $0)"' {} ; You missed the
PREFIX
and the last{}
that passes the file argument tosh
. Also I would use$0
rather{}
inside thesh
command. – cYrus – 2010-10-05T13:07:36.803