shell 脚本批量 mv 命令,如何提升速度?

2021-10-22 12:15:31 +08:00
 nowheretoseek

用 shell 对上万个文件批量重命名,每行一个 mv 命令,速度比较慢且 CPU 占用高,大约 70 秒跑 1000 行命令,应该跟每行开了一个进程有关,怎么避免这种情况?试了下将 1000 行 mv 写入一行并用分号分隔,没用。

1229 次点击
所在节点    问与答
10 条回复
dzdh
2021-10-22 12:28:27 +08:00
经常要这么干吗?

经常:源头解决,生成文件的时候就定好文件名,不能定的就写两份,定时删除老的
不经常:管他干啥,反正一次性的操作 sh xx.sh > /dev/null 2>&1 & 睡觉去
nowheretoseek
2021-10-22 12:31:05 +08:00
@dzdh 不经常,只是记得 shell 脚本中分行写与并行写有些什么不同来着,想试着解决下,却不行
AoEiuV020
2021-10-22 12:32:24 +08:00
如果确定瓶颈是创建进程,就随便换个脚本语言都可以单进程直接调用系统调用重命名的,
nowheretoseek
2021-10-22 12:37:17 +08:00
@AoEiuV020 是的,python 脚本或者写个 sublimetext 插件都可以解决此问题
mmtromsb456
2021-10-22 13:06:04 +08:00
应当试试用 rename 命令来正则重命名,应该 10k+文件重命名都是有规律的吧
ETiV
2021-10-22 13:15:58 +08:00
xargs 有一个 -P 参数,可以指定并发数
nowheretoseek
2021-10-22 14:13:05 +08:00
@mmtromsb456 有规律,但不是容易用规则表达的那种,还是编辑器做好列表再命名省事
huntagain2008
2021-10-22 15:27:50 +08:00
本人非程序员。
<试了下将 1000 行 mv 写入一行并用分号分隔,没用。
$ mv xxx xxx;mv xxx xxx;mv xxx xxx
这个是一串命令列表,前面的命令先运行,后面紧跟。实际和分行是一样的
$ mv xxx
$ mv xxx
如果将分号分隔那串命令两端加上圆括号,就成了进程列表,生成了子 shell 来执行对应的命令。
$ (mv xxx;mv xxx;mv xxx)
"在 shell 脚本中,经常使用子 shell 进行多进程处理。但是采用子 shell 的成本不菲,会明显拖慢处理速度。在交互式的 CLI shell 会话中,子 shell 同样存在问题。它并非真正的多进程处理,因为终端控制着子 shell 的 I/O 。

在交互式的 shell CLI 中,还有很多更富有成效的子 shell 用法。进程列表、协程和管道(后续会讲到)都利用了子 shell 。它们都可以有效地在交互式 shell 中使用。在交互式 shell 中,一个高效的子 shell 用法就是使用后台模式。在讨论如何将后台模式与子 shell 搭配使用之前,你得先搞明白什么是后台模式。
在 CLI 中运用子 shell 的创造性方法之一就是将进程列表置入后台模式。你既可以在子 shell 中进行繁重的处理工作,同时也不会让子 shell 的 I/O 受制于终端。
"
那么将进程列表置入后台模式效果怎么样呢?楼主要不然试试。
$ (mv xxx; mv xxx; 搞一千次)&
或者用协程
nowheretoseek
2021-10-22 17:04:28 +08:00
@huntagain2008 谢谢,我试着用这个办法重命名了 2600 个文件,用了 125 秒,之前的办法估计要用 170 秒,进步挺名显。感觉 shell 执行这个任务差不多就这样了,试了下用 python 脚本只需 1.3 秒
nowheretoseek
2021-10-22 17:05:35 +08:00
python 脚本备用
```
# coding: utf-8

import shutil
import time

names = [x.split("\t") for x in open("names.txt", "r").read().strip().split("\n")]
start = time.time()
for name in names:
old, new = name
shutil.move(old, new)
print(time.time() - start)
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/809767

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX