tags:

views:

532

answers:

8

I have a directory with files that look like this:

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

I ultimately want to create a new, empty PHP file whose name starts with the next number in the series.

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

The preceding code gives me a string like this:

LIST='001 002 004 005 '

I want to grab that 005, increment by one, and then use that number to generate the new filename. How do I do that in BASH?

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

So, that's bash-specific. Below is a any-posix-shell-including-bash solution, tho I imagine something simpler is possible.

$ 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
$
DigitalRoss
doesn't work with '008':
RC
That's because numbers starting with "0" are *octal*.
paxdiablo
Ok, octal bug fixed.
DigitalRoss
+1. I would have stuck with the bash solution since that's a specific tag.
paxdiablo
A: 

Here's a solution (you need 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
RC
You can also use `dc`: t=$(echo $f 1+pq | dc), or `expr`: t=$(expr $f + 1), or bash math: t=$(($f + 1))
mouviciel
+1  A: 
$ for file in *php; do last=${file%%_*} ; done
$ newfilename="test.php"
$ printf "%03d_%s" $((last+1)) $newfilename
006_test.php

i leave it to you to do the creation of new file

ghostdog74
+1  A: 

Do you need the whole LIST?

If not

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

will give you just the 005 part and

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

will print the next number in the sequence.

bmb
alternatively: printf "%03d" $(( 1 + $LAST ))
dave
+1  A: 

Fast, subshell-free and loop-free (also handles filenames with spaces)*:

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

Given your example files the output would be:

006_a_new_file.php
Dennis Williamson
+2  A: 

Using only standard tools, the following will give you the prefix for the new file (006):

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

This seems to be more simple.

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