Bash 使用mkdir创建名称递增的目录
我希望有一个bash脚本,它将创建一个名为“exam\u folder”的文件夹,如果这个文件夹已经存在(例如,我会再次运行脚本),脚本将创建“exam\u folder\u 1”,如果这个文件夹存在,我希望脚本创建“exam\u folder\u 2”等等。我想聪明点:) 我得到了这样的东西:Bash 使用mkdir创建名称递增的目录,bash,shell,directory,dash,ash,ksh,Bash,Shell,Directory,Dash,Ash,Ksh,我希望有一个bash脚本,它将创建一个名为“exam\u folder”的文件夹,如果这个文件夹已经存在(例如,我会再次运行脚本),脚本将创建“exam\u folder\u 1”,如果这个文件夹存在,我希望脚本创建“exam\u folder\u 2”等等。我想聪明点:) 我得到了这样的东西: function create_folder { if [ -d "$1" ]; then # if exists mkdir $1_`i_max` # function i_max woul
function create_folder {
if [ -d "$1" ]; then # if exists
mkdir $1_`i_max` # function i_max would find out the max number and add 1
else
mkdir $1
fi }
感谢您的帮助。两个答案:兼容和纯:
上次编辑:使regexp更精确,并更正一些计数错误
比如:
create_folder() {
if [ -e "$1" ] ;then
counter=1;
while [ -e "$1-$counter" ] ;do
counter=$((counter+1))
done
mkdir "$1-$counter";
else
mkdir "$1";
fi;
}
可以做:
$ ls -ltr /tmp |grep foo
$ create_folder /tmp/foo\ bar
$ create_folder /tmp/foo\ bar
$ create_folder /tmp/foo\ bar
$ ls -ltr /tmp |grep foo
drwxr-xr-x 2 user user 4096 1 mai 10:53 foo bar
drwxr-xr-x 2 user user 4096 1 mai 10:53 foo bar-1
drwxr-xr-x 2 user user 4096 1 mai 10:53 foo bar-2
或者使用更好的格式和另一种计数方式(如果存在多个目录,因为它使用了专门的计数功能,那么速度会更快,但是如果使用了forks,则时间会更长):
这在不同的实现下进行了测试:,和
并且dirname包含空格:
$ create_folder "foo bar"
$ create_folder "foo bar"
$ create_folder "foo bar"
$ create_folder "foo bar"
$ ls -ltr | grep foo
drwxr-xr-x 2 user user 4096 Apr 30 13:35 foo bar
drwxr-xr-x 2 user user 4096 Apr 30 13:35 foo bar-0001
drwxr-xr-x 2 user user 4096 Apr 30 13:35 foo bar-0002
drwxr-xr-x 2 user user 4096 Apr 30 13:35 foo bar-0003
对于球迷:
非常快速,没有分叉,格式也很好:
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ ls -ltr /tmp/ | tail -n 4
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0001
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0002
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0003
这应该适用于任何符合POSIX的shell(尽管我不能100%确定
[“$foo”-eq“$foo”]
是数字检查)。我在dash
和busybox'ash
下对它进行了快速测试
create_folder()
{
if [ -e "$1" ]; then
i=0
for d in "$1"_*; do
_i="${d##*_}"
[ "${_i}" -eq "${_i}" ] 2>/dev/null && i="${_i}"
done
i=$((i+1))
mkdir "$1_${i}"
else
mkdir "$1"
fi
}
您可以这样做:
max=`ls -1d exam_folder* | tr -dc '[0-9\n]' | sort -k 1,1n | tail -1`
mkdir exam_folder_$((max + 1))
请注意,如果您同意的话,它不会填补序列中的“漏洞”。这可能会有帮助:否。除此之外,试着运行两到三次
create_文件夹“foo bar”
,看看你的代码还有什么问题。@AdrianFrühwirth好的,我错过了一个双引号:printf“%s-%04d”“$1”
。与纯bash相比,它的主要优点是在busybox下工作。@AdrianFrühwhirth由于在ls
和wc-l
之间有一个grep
,所以不解析ls的输出在这里并不重要,但无论如何还是要感谢。它在busybox下工作是编写不必要的丑陋代码的不好借口。另外,由于你只计算行数,如果有像foobarqux
这样的文件夹,它会考虑这些,不必要地跳过这些索引(这不是错误的行为,但不是用户可能期望的)。@AdrianFrühwirth我不确定我的代码比你的代码更难看(我发现使用变量名,如counter
和nname
比d
和I
;-)更具可读性。无论是否使用fork,它都可以工作,并保持兼容。
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ create_folder "/tmp/foo bar"
$ ls -ltr /tmp/ | tail -n 4
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0001
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0002
drwxr-xr-x 2 user user 4096 1 mai 11:17 foo bar-0003
create_folder()
{
if [ -e "$1" ]; then
i=0
for d in "$1"_*; do
_i="${d##*_}"
[ "${_i}" -eq "${_i}" ] 2>/dev/null && i="${_i}"
done
i=$((i+1))
mkdir "$1_${i}"
else
mkdir "$1"
fi
}
max=`ls -1d exam_folder* | tr -dc '[0-9\n]' | sort -k 1,1n | tail -1`
mkdir exam_folder_$((max + 1))