Batch rename files

2019-01-22 03:34发布

I want to batch re-name a number of files in a directory so that the preceding number and hypen are stripped from the file name.

Old file name: 2904495-XXX_01_xxxx_20130730235001_00000000.NEW
New file name:         XXX_01_xxxx_20130730235001_00000000.NEW

How can I do this with a linux command?

9条回答
来,给爷笑一个
2楼-- · 2019-01-22 03:56

You can use this tool: rnm

Code to do what you want:

rnm /path/to/the/directory -fo -dp -1 -rs '/^\d+-//' -ss '^\d+-'

-fo is for file only mode
-dp is the depth of directory ( -1 means unlimited depth).
-rs is replace string. \d+- regex is being replaced with empty string.
-ss is search string, it searches for files with ^\d+- regex. (It could be omitted though, some harmless error messages would be printed on screen).

查看更多
Melony?
3楼-- · 2019-01-22 04:04

I really like something as "rename *.mp3 *.mp4".

But none of other answers give me that. So I wrote a haskell program to do it.

https://hackage.haskell.org/package/batch-rename

With this you can do: batch_rename "DCIM*.jpg" "*.png"

查看更多
唯我独甜
4楼-- · 2019-01-22 04:06

There is also a handy GUI tool pyRenamer https://wiki.ubuntuusers.de/pyRenamer/

查看更多
何必那么认真
5楼-- · 2019-01-22 04:11

This might look a little complex, but it's pretty effective and works well on both *nix and OSX systems. It also acts recursively, renaming files in the current directory as well as any subdirectories:

find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \
cp temp1 temp2 && \
vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \
paste temp1 temp2 > temp3 && \
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
sh ./temp3 && \
rm temp1 temp2 temp3

Here's a breakdown of what just happened:

The first line says to find (find) all files, starting with those in the current directory (.), whose name matches the pattern (-regex) of "7 numbers, followed by a dash, followed by 0 or more characters" ('.*/[0-9]\{7\}[-].*'), and write those file names and their respective paths (-print) to a file called temp1 (> temp1). Note that the -print directive is probably not necessary in most cases but it shouldn't hurt anything.

find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \

Then, copy (cp) the contents of temp1 to a file called temp2.

cp temp1 temp2 && \

Next, open the file temp2 using the vi text editor and give vi two commands (using -c to signify each new command):

  1. Command #1:
    • Search each line of temp2 (:g) for the same pattern we searched for above, except this time group the results using parentheses (\([0-9]\{7\}[-]\)\(.*\)).
    • For each matching line, move the cursor to where the match was found and replace the whole match with only the second group of the matched pattern (\2).
  2. Command #2:
    • Save the changes made to temp2 and close the file (:x).

The result of which being this:

 vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \

Now, concatenate the lines from temp1 with those of temp2 (paste) and write each newly combined line to a file called temp3 (> temp3).

paste temp1 temp2 > temp3 && \

Next, run vi again, doing the same steps as above except this time search for the beginning of each line (^) inside the file temp3 and add mv and one space right after it (mv).

vi -c ":g/^/s//mv /" -c ":x" temp3 && \

Then, execute the contents of temp3 (./temp3) as a shell script (sh).

sh ./temp3 && \

Finally, remove (rm) each of the temporary files we created during the whole process.

rm temp1 temp2 temp3
查看更多
Anthone
6楼-- · 2019-01-22 04:11

vimv lets you rename multiple files using Vim's text editing capabilities.

Entering vimv opens a Vim window which lists down all files and you can do pattern matching, visual select, etc to edit the names. After you exit Vim, the files will be renamed.

The screencast in the README file shows how it solves original poster's question.

[Disclaimer: I'm the author of the tool]

查看更多
够拽才男人
7楼-- · 2019-01-22 04:12

This should make it:

rename 's/^[0-9]*-//;' *

It gets from the beginning the block [0-9] (that is, numbers) many times, then the hyphen - and deletes it from the file name.


If rename is not in your machine, you can use a loop and mv:

mv "$f" "${f#[0-9]*-}"

Test

$ ls
23-aa  hello aaa23-aa
$ rename 's/^[0-9]*-//;' *
$ ls
aa  hello aaa23-aa

Or:

$ ls
23-a  aa23-a  hello
$ for f in *;
> do
>   mv "$f" "${f#[0-9]*-}"
> done
$ ls
a  aa23-a  hello
查看更多
登录 后发表回答