1

I would like to rename multiple files, but not just appending my string to the end or the beginning of the file. I would like to place it in a specific location. This is the command I am working with right now, but it can only add things at the beginning and the end of the file name.

for f in `ls  ~/tmp/*`; do FILE=`basename $f`; echo "Rename:"$f;echo $FILE; mv "$f" "/home/tmp/JC_"${FILE%.*}"_hg19."${FILE#*.}"";  done

Lets say the file names are as follows hell_1.txt (and lets say there is a ton of them each with a different number for simplicity) I would like to add an o into the file name so the resulting name would be hello_1.txt it would be nice if you had a general solution not just for this example.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
crysis405
  • 1,121
  • 2
  • 13
  • 26

3 Answers3

2

this should work:

for x in ~/tmp/*.txt; do mv $x `echo $x | sed -e 's#hell#hello#'`; done
Damell
  • 59
  • 6
  • Exactly. However, don't get used to the backtick. Use `$(...)` instead, as [backticks are deprecated](http://stackoverflow.com/a/4708569/912144) – Shahbaz Mar 27 '13 at 11:21
  • Backticks aren't going anywhere anytime soon, but `$()` is cleaner and nests. If you can guarantee you will only be using Bash (and not simply a POSIX shell), you can replace the backticks like so: `mv $x ${x/hell/hello};`. See [the Bash manual](https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion) for more, and [the POSIX shell reference](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02) for what /bin/sh is guaranteed to support. – bonsaiviking Mar 27 '13 at 11:29
  • not quite working, maybe I've oversimplified this. Lets say you have your `hell_1.txt` but then you have a sting after `hell` that changes and after that string you want to add the `o`. I not sure if in sed you can use wildcards to give you something like this `| sed -e 's#hell*_#hell*o_#` – crysis405 Mar 27 '13 at 12:00
  • try changing the sed to: sed -e 's#hell[^_]*#hello#' – Damell Mar 27 '13 at 12:13
  • this removes the string that the wildcard was supposed to call, any way to include it in the final hello? (so something like this: hell12o ; 12 being the *) – crysis405 Mar 27 '13 at 12:34
  • it is really hard to tell exact solution not knowing all the different cases that the command needs to involve. You need to tell exact specification – Damell Mar 27 '13 at 12:51
  • @crysis405 : i replied to you additionnal infos and questions in my answer : please have a look (it couldn't fit in a comment here anymore) – Olivier Dulac Mar 27 '13 at 13:31
0

How about

rename 's/hell_/hello_/' /tmp/*.txt
anishsane
  • 20,270
  • 5
  • 40
  • 73
0

if i understand you wish to change any "hell.*_NNN.txt" to "hel.*o_NNN.txt" (keeping the .* between "hell" and "_NNN.txt" (NNN being any number).

then:

for x in ~/tmp/*.txt; do 
   mv "$x" "$(echo "$x" | LC_COLLATE=C sed -e 's#\(hell.*\)\(_[0-9]*\.txt$\)#\1o\2#')"
done

I added the LC_COLLATE=C during sed invocation so you can rely on the "[0-9]" matching only digits '0' or '1' or ... or '9'

(If you wonder why adding the LC_COLLATE: with some locales [A-Z] could match every letters A-Z or a-y (except 'z'!) as in such locales letters appears in this order: 'A' 'a' 'B' 'b' ... 'Z' 'z'. And with other locales, who knows?)

(note: you could also replace "[0-9]" with the "[[:digit:]]" notation, but it could be less portable : "old" version of sed won't know about this notation and will try to match any of '[' or ':' or ... or 't' or ':', followed by a ']' (*, so 0,1 or more times) ... That's why I don't like using those special [[:things:]] with sed, tr, etc : i see them as less portable. Use perl instead if you prefer to use those?)

Olivier Dulac
  • 3,695
  • 16
  • 31
  • sorry but you will need to explain this to me a bit more. So you first have `(hell.*\)` I'm guessing that this give you all the hell.(whatever is here i.e. the "12")"_1.txt" (numbers being the changing variable)(a little change from the original format I guess). Then you cycle through the numbers "_1.txt" "_2.txt" and so on keeping txt a constant (I actually have different extensions for different files so would something like `${FILE#*.}` work here?) and finally you add the `o` but I am not clear what the 1 and 2 are since the 12 was in the wildcard call? – crysis405 Mar 27 '13 at 15:54
  • 1
    `s#\(something1\)\(something2\)#\1o\2#` : tells sed to match "something1something2" and the `\(...\)` delimitates areas and place them in registers (\1 being the first register, \2 the 2nd, etc). So it says: For each lines matchings "something1something2", place in register \1 "something1", and place in register \2 "something2 , and then replace with \1o\2 (so will replace with : "something1osomething2" (as : sed -e 's#REGEXP#replacement#' will search for a regexp "REGEXP", and replace it with "replacement") – Olivier Dulac Mar 27 '13 at 17:53
  • if you need further explanation, please ask (but I won't be able to reply before late this evening, unless you ask very soon ^^) – Olivier Dulac Mar 27 '13 at 17:54
  • 1
    in a regexp : '.' matches any character. '.*' matches : "any characters, repeazted 0,1 or more times". a* : would match "" or "a" or "aaaa" or "aaaaaaaaaaaaaaaa" . here i said : match anything starting with "hell" (followed by any characters, 0 1 or more times, ie : it maches "hell" "hellAZAEAZE" "hell^" etc. – Olivier Dulac Mar 27 '13 at 17:56
  • 1
    '\.' is a backspace before ., making "." not the special "any character", but instead the literral ". character" (and only that one). so "\.txt" matches only things containing ".txt" (whereas ".txt" would match any character followed by txt, ie ".txt" or "Atxt" or " txt" or ....). and finally "$" means "end of the line", so "\.txt$" matches only lines ENDING in ".txt" – Olivier Dulac Mar 27 '13 at 17:58
  • you could try regexp on : [RegExr](http://gskinner.com/RegExr/) to try regexp (you can choose various flavor of regexes: there are the regular (legacy) ones, the extended ones, the perl ones, etc : each have common thiongs, and some have extensions (or behave differently in some cases). Read about [POSIX regexp on wikipedia](http://en.wikipedia.org/wiki/Regular_expression#POSIX) – Olivier Dulac Mar 27 '13 at 18:06