有时我需要将macOS系统上的文件批重命名为随机或伪随机文件名,只需八个小写字母和数字,例如从mcmurdo-station.png类似于a12bc0xy.png型。为此,我使用CRC32:

对于f in*.png;执行mv$f$(crc32$f);完成

但有一个缺点,即如果同一文件夹中有两个相同的文件,则它们具有相同的校验和,因此会发生文件名冲突。当然,通常我不会在同一个文件夹中存储相同的文件,但我还是希望在批量重命名时避免这种过度自动化。

我在互联网上发现的另一种方法是使用base64:

randomname(){head-c8/dev/urandom|base64|tr-dc a-z0-9;}zmv'(*)。(*)“”“随机名称”$2'

2024-05-22编辑:代替反引号,最好用美元符号:

zmv“*(.*)”“$(随机名称)$2”

但结果文件名的长度不同:第一个测试文件是从foo.png格式52拉德·彭,而第二个-来自巴林pxg.png格式.

还有一个使用的解决方案随机播放来自GNU核心实用程序:https://unix.stackexchange.com/a/259761,但目前我更希望找到一种不需要安装第三方软件包的方法。

什么是好的简单的替代方案?

11
  • 2
    “但结果文件名的长度不同”–</dev/uradom base64|tr…|head… 评论 5月19日16:39
  • 2
    基数64动态编码。要生成散列,需要终止输入流。从开始</dev/uradom头-c N(选择您的N个)并由此生成CRC32。 评论 5月19日18:47
  • 2
    我建议,如果您试图避免名称空间冲突,没有“简单”的答案,因为您需要某种形式的“内存”来避免冲突。碰撞至少意味着你没有事实上不过,数据会以这种方式丢失,因为文件一开始就是一个复制品,您可以用“硬链接”来替换它。 已发表评论 5月20日8:37
  • 2
    关于乌伊德根? 这还不够吗?
    – 哈斯塔
    评论 5月21日9:10
  • 2
    我很好奇:为什么需要将文件重命名为随机文件名?(因此是不可逆的,除非您打算使用校验和和列表重新命名?) 评论 5月21日11:27

4个答案4

重置为默认值
9

您只需将文件重命名为递增的数字,只需按随机顺序处理它们。

random()REPLY=$randomn=0;zmv“*(.*)(#qo+random)”“${(l[8][0])$((++n))}$1”

这里使用l[长度][衬垫]左路加法参数扩展标志,将带0的数字左移到8。

示例(此处带有-n个用于试运行):

$n=0;zmv-n“*(.*)(#qo+random)”“${(l[8][0])$((++n))}$1”mv--21.jpg 00000001.jpgmv--2111.jpg 00000002.jpgmv--111.jpg 00000003.jpgmv--2.jpg 00000004.jpg格式mv--00012.jpg 00000005.jpgmv--211.jpg 00000006.jpg(最小值)mv--10012.jpg 00000007.jpg(百万伏)mv--11.jpg 00000008.jpgmv--1111.jpg 00000009.jpgmv--1.jpg 00000010.jpg(百万伏)

对于随机字符串a-z型信件和0-9数字,您可以使用以36为基数的随机数(对于8位长的数字,在0到36#ZZZZZ范围内)

zmodload zsh/mathfunczmv“*(.*)”“${(Ll[8][0])$(([##36]36#100000000*rand48()))}$1”

(添加要转换为小写的参数扩展标志)

请注意,虽然可能性极小,但不能保证不会发生任何碰撞(尽管zmv公司将检测到它并在进行任何重命名之前退出)。

$zmv-n“*(.*)”“${(Ll[8][0])$(([##36]36#100000000*rand48()))}$1”mv--00012.jpg 60m34z1w.jpg格式mv——10012.jpg 4ff2b06p.jpgmv——1111.jpg n2mac2r4.jpgmv--111.jpg dwf72mfg.jpgmv--11.jpg 3nef10qd.jpgmv--1.jpg lggtk364.jpgmv--2111.jpg am7sd85t.jpg格式mv--211.jpg 35n7ebtn.jpg格式mv--21.jpg eussspd7.jpgmv--2.jpg 9jjgiw08.jpg格式

为了避免冲突,可以定义一个铀()数学函数,根据先前生成的数字的记录列表检查生成的数字,如果看到则重试:

铀(){整数nwhile((见[$((n=rand48()*$1))]++))continue((n))}zmodload zsh/mathfunc函数-M和1typeset-A seen=()zmv“*(.*)”“${(Ll[8][0])$(([##36]urand(36#100000000))}$1”
2
  • 非常感谢,斯特芬。“对于包含a-z字母和0-9位数字的随机字符串,您可以使用以36为基数的随机数。”-您能解释一下从实际角度来看,这种方法与使用以16为基数的方法有何不同吗?该方法在问题中提到,并在评论中进一步讨论过?
    – jsx97型
    已发表评论 5月20日8:48
  • 2
    @jsx97,不知道你在问什么。首先,这种方法根据需要使用0-9a-z字符,而基本16个字符只使用0-9a-f字符(我的第一个字符仅使用0-9)。它也不依赖于除兹什,不派生也不执行任何操作(除了毫伏由调用zmv公司但您也可以启用内置百万伏特具有zmodload zsh/文件). 它不依赖于地区。 评论 5月21日17:33

首先,我建议,如果你有相同的校验和,你可能有相同的内容。除名称外,最好保留所有副本。在这种情况下,使用名称作为输入。但是,如果您在不同的内容上遇到校验和冲突,请使用md5sum,它是128位而不是32位,这样可以将概率降低到可以忽略的水平。我过去曾使用它进行唯一性检查,以防32位校验和发生冲突的可能性非常高。

假设您确实希望能够处理具有相同内容和不同名称的文件

我有一个不同的情况,决定映射到任意唯一值,这将适应-自动彩色编码地图绘图;我希望它们在重新加载时保持不变。我通过文件的简单散列生成唯一值的一部分名称,并将其映射到红色通道。绿色是根据文件名的长度生成的。在这个上下文中应用相同的方法给了我们(注意echo用于演示目的)。

注意,这里我使用md5sum,因为它和128位输出一样,可以通过简单的技巧应用于字符串(文件名)。

用于*.jpg中的文件名;newfilename=$(echo-n“$filename”|md5sum|cut-d''-f 1)newfilename=$newfilename${#filename}echo mv--“$filename”“$newfilename.jpg”完成

如果新文件名比您想要的长,您可以替换切割-d“-f 1命令切割-c1-10或者你想要多少位数,当然,这是以增加碰撞的机会为代价的。

老实说,我很怀疑你需要的不是md5总和名称上;我附加长度只是为了完成与我的过程的类比,并演示如果坚持使用CRC32,您将如何进行类比。

如果你愿意,你可以改为处理文件的日期;我特别不想这样做,因为我不想在重新下载文件时更改绘图颜色。您还可以将文件校验和用于名称的一部分,将文件名散列用于另一部分。

顺便说一句,标准警告-MD5对安全性没有好处,所以不要使用它。

4
  • 你好,克里斯。目前对我不起作用;我想您在不同的操作系统上进行了测试,可能是Linux,而我需要它在macOS上工作。第一个问题是,如果我只是“按原样”执行此代码zsh:找不到命令:md5sum错误。然后我换了md5总和具有crc32型并删除了这两个回声,但仍然不起作用。
    – jsx97型
    评论 5月20日12:06
  • 1
    @jsx97 crc32只能处理文件内容,至少在我知道的系统上是这样。然而,zsh上缺少md5sum让我感到惊讶。这个回声最后是要删除的,但其中有一个错误需要我首先修复(我最初将旧复制到新,然后删除旧,并错误地合并了行) 评论 5月20日12:43
  • 1
    …来自这个答案你可以尝试替换md5总和具有md5型。正如我认为这不是zsh的问题,而是MacOS使用了不同的名称。这意味着我无法测试它 评论 5月20日12:48
  • 1
    非常感谢你的回答,克里斯。更换后md5总和具有md5型并移除第二个回声,它起作用了。
    – jsx97型
    评论 5月20日19:22
2

另一种方法是只要存在第一个随机名称的文件,就重新生成随机名称。大致如下:

randomname(){base64</dev/uradom|tr-dC a-z0-9|head-c4;}对于f in*.png;newName=$(randomname).png而[-e“$newName”];newName=$(randomname).png完成mv--“$f”“$newName”完成
10
  • 谢谢,特顿。确定这里没有错误吗?它产生tr:非法字节序列错误。
    – jsx97
    评论 5月20日11:03
  • @jsx97 hmm.不,在我的系统(Arch Linux)上运行良好。你确定你准确地复制了它吗?您可以手动运行`tr-dc a-z0-9</dev/urandom|base64|head-c4`吗?这样行吗?
    – 特顿
    评论 5月20日11:21
  • 正在执行tr-dc a-z0-9</dev/urandom|base64|head-c4其本身也会产生同样的结果tr:非法字节序列错误。这是在macOS上,zsh 5.9(x86_64-apple-darwin23.0)
    – jsx97型
    评论 5月20日11:27
  • 啊,对不起,我没注意到这是一个macOS系统。根据macOS操作系统信托收据手册页,我想你需要tr-dC a-z0-9</dev/urantom|base64|head-c4(即资本-C类对于信托收据). 这是否如预期的那样有效?
    – 特顿
    评论 5月20日11:30
  • 1
    唉,对不起@jsx97,我实际上没有保存编辑。我以为我有,但它在另一个选项卡中打开了。我想问你是否可以看到版本现在作品。我的错。
    – 特顿
    评论 5月20日12:06
1

使用带有模板和您选择的其他标志的mktemp命令:https://ss64.com/mac/mktemp.html

此命令生成一个不存在的唯一随机文件名,创建一个具有该名称的空文件,并打印该名称。然后,您可以自由地在文件顶部重命名文件。

1
  • 实际实现是什么样子的?
    – 叮当声
    评论 5月26日20:41

你必须登录来回答这个问题。

不是你想要的答案吗?浏览标记的其他问题.