使用 bash 自动生成文件名

使用 bash 自动生成文件名

假设我有这样的文件:

out-1.avi

我想要一段 bash 代码,它可以为我提供此类列表的下一个文件名:

out-1.avi
out-2.avi
out-3.avi
etc.

编辑我需要实现的是获取网络摄像头录制脚本的下一个文件名,这样它就不会覆盖!

答案1

我不知道上下文,但以下循环包含您需要的所有元素:-

n=0; while (($n < 10)); do ((++n)); echo name=out-$n.avi; done

这将列出序列中的前 10 个文件。

经过您的编辑,我看到了几个答案。

对原始循环进行简单修改如下:-

n=1; while [ -f out-$n.avi ]; do ((++n)); done; echo name=out-$n.avi

这对于少量文件来说会很有效,但是当文件数量增加到数百个时,它会变得越来越低效。

更有效的答案是将最新的文件编号保存在其自己的文件中:-

n=`line<avicount.text`; ((++n)); echo "$n">avicount.text; echo name=out-$n.avi

每次调用时,此脚本都会生成一个新名称,但依赖于avicount.text始终与正在使用的文件和名称保持同步。

总体而言,更好的解决方案是使用时间戳而不是序列号:-

echo name=out-`date +%Y%M%d%H%m%S`.avi

这将根据脚本调用时的秒数给出一个唯一的名称,将文件的创建时间包含在其名称中会很有用。此方案还允许随意删除、存档或以其他方式移动文件,而不会影响将来的文件名。

答案2

您可以使用它seq来生成值,然后touch创建文件。

for n in $(seq 1 5)
do
    touch out-${n}.avi
done

答案3

#!/bin/bash
LAST=$(find . -maxdepth 1 -name "*.avi" -type f -printf "%p\n" | sed -e s/.\\/out-//g -e s/.avi//g | sort -g | tail -1)
touch out-$(($LAST + 1)).avi
  • 第一行选择目录中最后修改的 avi 文件(不递归),并提取其名称中的数字。
  • 第二行在原先的名称上加1并生成文件。

答案4

@jherran 提供的解决方案应该可以满足您的需求。如果您只是希望脚本您下一个文件名,而不是为您创建它,将脚本末尾的“touch”更改为“echo”。

但是,随着您添加许多文件,这会变得越来越慢。如果您需要连续的数字,您可以将当前数字写入文件,然后在写入下一个文件之前将其读回,写出新数字,然后写出文件。我在下面提供了执行此操作的示例代码。

但是,如果您不需要连续的数字,而只是想要不冲突的文件名,那么日期戳就非常有用。它们按您期望的方式排序,如果您不进行时间旅行,它们会单调递增。

对于您提出的这个问题 (shell 脚本返回下一个值) 的答案,基于我上面关于仅使用计数器文件的建议,如下所示:

#!/usr/bin/sh

if [ -f counter.txt ]; then
{
   VAL=`cat counter.txt`
   echo "out-$VAL.avi"
   VAL=`expr $VAL + 1`
   echo "$VAL" > counter.txt
   exit 0
}
fi
echo "out-1.avi"
echo "2" > counter.txt
exit 0

或者,如果您想采用我的建议,使用日期戳来实现唯一性和排序,只需让您的文件写入程序抓取此命令的输出:

 date +%F-%T

或者任何你认为有用的日期和时间粒度。上面的代码会给你类似这样的结果:

2014-12-01-16:41:33

在末尾加上“.avi”您就拥有了带时间戳的文件名,精确到秒。

相关内容