Linux 批量重命名文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18743284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Batch rename files
提问by van
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?
如何使用 linux 命令执行此操作?
采纳答案by fedorqui 'SO stop harming'
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.
它从头开始[0-9]
多次获取块(即数字),然后是连字符-
并将其从文件名中删除。
If rename
is not in your machine, you can use a loop and mv
:
如果rename
不在您的机器中,您可以使用循环和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
回答by David Souther
If the first numbers are always the same length:
如果第一个数字总是相同的长度:
for F in *new ; do
mv $F ${F:8}
done
The ${parameter:number}
does a substring expansion - takes the string starting at the 8th character.
在${parameter:number}
做了子扩张-需要字符串开始在第8字符。
There are many other string edits available in expansions to handle other cases.
扩展中还有许多其他字符串编辑可用于处理其他情况。
回答by Lloyd
回答by doms
I think this command would better if you execute the command below:
如果您执行以下命令,我认为此命令会更好:
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 mv
Here
ls *- lists files in curent folder
sed -e- executes expression
p;- prints old file name
s/old-name/new-name/- produce new filename
xargs -n2- handles two arguments to mv
mv- gets two parameters and do move operation
这里
ls *- 列出当前文件夹中的文件
sed -e- 执行表达式
p;- 打印旧文件名
s/old-name/new-name/- 产生新文件名
xargs -n2- 处理两个参数给 mv
mv- 获取两个参数并执行移动操作
Recommendation:before executing mv verify what you do is what you want to achieve with echo.
建议:在执行 mv 之前验证你所做的是你想用echo实现的。
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 echo
Following example renames
以下示例重命名
SCCF099_FG.gz5329223404623884757.tmp to
SCCF099_FG.gz
SCCF099_FG.gz5329223404623884757.tmp 到
SCCF099_FG.gz
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 echo
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 mv
回答by jerdiggity
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:
这可能看起来有点复杂,但它非常有效并且在 *nix 和 OSX 系统上运行良好。它还递归地操作,重命名当前目录以及任何子目录中的文件:
find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \
cp temp1 temp2 && \
vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s///" -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
“ 7 个数字,后跟一个破折号,后跟 0 个或多个字符” ( '.*/[0-9]\{7\}[-].*'
)的模式 ( )匹配,并写入这些文件名及其各自的路径 ( -print
) 到名为temp1( > temp1
)的文件。请注意,该-print
指令在大多数情况下可能不是必需的,但它不应该伤害任何东西。
find . -regex '.*/[0-9]\{7\}[-].*' -print > temp1 && \
Then, copy (cp
) the contents of temp1to a file called temp2.
然后,将temp1cp
的内容复制 ( )到名为temp2的文件中。
cp temp1 temp2 && \
Next, open the file temp2using the vitext editorand give vi two commands (using -c
to signify each new command):
接下来,使用vi文本编辑器打开文件temp2并给 vi 两个命令(用于表示每个新命令):-c
- 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
).
- Search each line of temp2(
- Command #2:
- Save the changes made to temp2and close the file (
:x
).
- Save the changes made to temp2and close the file (
- 命令#1:
- 在temp2(
:g
) 的每一行中搜索我们在上面搜索的相同模式,除了这次使用括号 (\([0-9]\{7\}[-]\)\(.*\)
)对结果进行分组。 - 对于每个匹配行,将光标移动到找到匹配的位置,并仅用匹配模式的第二组 (
\2
)替换整个匹配。
- 在temp2(
- 命令#2:
- 保存对temp2所做的更改并关闭文件 (
:x
)。
- 保存对temp2所做的更改并关闭文件 (
The result of which being this:
结果是这样的:
vi -c ":g/\([0-9]\{7\}[-]\)\(.*\)/s///" -c ":x" temp2 && \
Now, concatenate the lines from temp1with those of temp2(paste
) and write each newly combined line to a file called temp3(> temp3
).
现在,将temp1 中的行与temp2( paste
) 中的行连接起来,并将每个新合并的行写入一个名为temp3( > temp3
)的文件中。
paste temp1 temp2 > temp3 && \
Next, run viagain, doing the same steps as above except this time search for the beginning of each line (^
) inside the file temp3and add mvand one space right after it (mv
).
接下来,再次运行vi,执行与上述相同的步骤,除了这次^
在文件temp3 中搜索每一行的开头 ( ) 并在其后面添加mv和一个空格 ( mv
)。
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
Then, execute the contents of temp3(./temp3
) as a shell script (sh
).
然后,将temp3( ./temp3
)的内容作为 shell 脚本 ( sh
) 执行。
sh ./temp3 && \
Finally, remove (rm
) each of the temporary files we created during the whole process.
最后,删除 ( rm
) 我们在整个过程中创建的每个临时文件。
rm temp1 temp2 temp3
回答by Jahid
You can use this tool: rnm
你可以使用这个工具: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).
-fo
仅用于文件模式-dp
是目录的深度(-1
意味着无限深度)。-rs
是替换字符串。\d+-
正则表达式被替换为空字符串。-ss
是搜索字符串,它使用^\d+-
正则表达式搜索文件。(虽然可以省略,但屏幕上会打印一些无害的错误消息)。
回答by Joyer
I really like something as "rename *.mp3 *.mp4".
我真的很喜欢“重命名 *.mp3 *.mp4”之类的东西。
But none of other answers give me that. So I wrote a haskell program to do it.
但是其他答案都没有给我。所以我写了一个haskell程序来做到这一点。
https://hackage.haskell.org/package/batch-rename
https://hackage.haskell.org/package/batch-rename
With this you can do: batch_rename "DCIM*.jpg" "*.png"
你可以这样做:batch_rename "DCIM*.jpg" "*.png"
回答by Peter T.
There is also a handy GUI tool pyRenamer
https://wiki.ubuntuusers.de/pyRenamer/
还有一个方便的 GUI 工具pyRenamer
https://wiki.ubuntuusers.de/pyRenamer/
回答by thameera
vimvlets you rename multiple files using Vim's text editing capabilities.
vimv允许您使用 Vim 的文本编辑功能重命名多个文件。
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.
输入 vimv 会打开一个 Vim 窗口,其中列出了所有文件,您可以进行模式匹配、视觉选择等来编辑名称。退出 Vim 后,文件将被重命名。
The screencastin the README file shows how it solves original poster's question.
README 文件中的截屏视频显示了它如何解决原始海报的问题。
[Disclaimer: I'm the author of the tool]
[免责声明:我是该工具的作者]