BASH:在名称以数字(ls,sed)开头的目录中查找编号最大的文件名

时间:2009-10-19 05:09:04

标签: bash shell sed ls

我有一个包含以下文件的目录:

001_something.php  002_something_else.php
004_xyz.php        005_do_good_to_others.php

我最终想要创建一个新的空PHP文件,其名称以系列中的下一个数字开头。

LIST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | tr '\n' ' '`

上面的代码给了我一个这样的字符串:

LIST='001 002 004 005 '

我想获取005,递增1,然后使用该数字生成新文件名。我如何在BASH中做到这一点?

9 个答案:

答案 0 :(得分:12)

你需要整个LIST吗?

如果不是

LAST=`exec ls $MY_DIR | sed 's/\([0-9]\+\).*/\1/g' | sort -n | tail -1`

只会给你005部分和

printf "%03d" `expr 1 + $LAST`

将打印序列中的下一个数字。

答案 1 :(得分:10)

$ LIST=($LIST)
$ newfile=`printf %03d-whatever $((10#${LIST[${#LIST}]}+1))`
$ echo $newfile
006-whatever

所以,这是特定于bash的。下面是一个 any-posix-shell-including-bash 解决方案,我认为可以采用更简单的方法。

$ cat /tmp/z
f () {
    eval echo \${$#} | sed -e 's/^0*//'
}
LIST='001 002 004 005 '
newname=`printf %03d-whatever $(($(f $LIST) + 1))`
echo $newname
$ sh /tmp/z
006-whatever
$ 

答案 2 :(得分:7)

仅使用标准工具,以下内容将为您提供新文件的前缀(006):

ls [0-9]* | sed 's/_/ _/' | sort -rn | awk '{printf "%03d", $1 + 1; exit}'

答案 3 :(得分:3)

这似乎更简单。

ls [0-9]* | sort -rn | awk '{FS="_"; printf "%03d_new_file.php\n",$1+1;exit}'

答案 4 :(得分:2)

Fast,subshel​​l-free和loop-free(也处理带空格的文件名)*:​​

list=([0-9]*)
last=${list[@]: -1}
nextnum=00$((10#${last%%[^0-9]*} + 1))
nextnum=${nextnum: -3}
touch ${nextnum}_a_new_file.php

鉴于您的示例文件,输出将为:

006_a_new_file.php

答案 5 :(得分:1)

$ for file in *php; do last=${file%%_*} ; done
$ newfilename="test.php"
$ printf "%03d_%s" $((last+1)) $newfilename
006_test.php

我留给你做新文件的创建

答案 6 :(得分:1)

  1. touch "newfile_$(printf "%03d" $(echo $(ls 00?_*.php|sed 's/_.*//'|sort -rn|head -1)+1|bc))"
    

    2

    num=$(ls 00?*.php|sed 's/.*//'|sort -rn|head -1) 
    touch $(printf "newfile_%03d" $((num+1)))

答案 7 :(得分:1)

我发布这个答案,提出核心问题的最小解决方案"在名称以数字开头的目录中找到编号最高的文件名":

@FormUrlEncoded

第一个语句将MyDir中的文件作为一个带有-1选项的衬里。这通过管道输出到排序函数,该函数使用-h以人类数字顺序排序,并且使用-r以相反的顺序(最高编号)排序。这通过管道传递到头部功能,它只提供-n最高的结果(在示例中为1)。 答案考虑人类数字排序顺序,即221高于67.它是一个POSIX shell解决方案,因此高度兼容。

答案 8 :(得分:0)

这是一个解决方案(你需要bc):

#!/bin/bash

LIST='001 002 008 005 004 002 '
a=0

for f in $LIST
do
    t=$(echo $f + 1|bc)
    if [ $t -ge $a ]
    then
        a=$t
    fi
done

printf "%03d\n" $a