13

I want to create a directory with a number at the end, e.x. "dir1", and increment that number if the directory already exists until it hits a directory name that doesn't exist, and I need to do this in a single line in a Linux command line, something like:

mkdir --increment dir$

How would I go about doing that?

So far I've got this:

dir=output; n=0; mkdir -p $dir$n; if test -d $dir$n; then n=$((n+1)); echo $dir$n; fi

But it just echos the next dir name, I need it to recursively execute the command.

5 Answers5

26

This is a trivial exercise in the use of while:

n=0
while ! mkdir dir$n
do
    n=$((n+1))
done

But of course it doesn't take much thought to realize that this trivial mechanism doesn't scale well.

So instead of reinventing the wheel and having to shave off all of the corners again, one creates unique temporary directories from a template slightly differently:

name=$(mktemp -d dirXXXXXXXXXXX)
JdeBP
  • 27,556
  • 1
  • 77
  • 106
7

If you just want to incrementally create directories that are listed in the correct order, may I instead recommend folders that are named based on the current date?

DATE=$(date +%F)
mkdir "dir-$DATE"

It will create directories with the names like dir-2014-03-02 (YYYY-MM-DD, so as to appear in alphabetical order).

If you create more than one directory per day, you can add the current time to the file name. See man date on how to tweak the output formatting of date.

IQAndreas
  • 4,337
6

find the "biggest" dirname first, get the number and increment that:

last_dir=(printf "%s\n" dir* | sort -Vr | head -1)
num=$(last_dir#dir)
mkdir "dir$((num+1))"
glenn jackman
  • 27,524
3

Assuming your directories always start off at "dir1", and that there are no files named $dir* (iE they are all sequentially numbered directories), you can get away with this one liner -

mkdir ${dir}$(( `ls ${dir}* | wc -w` + 1 ))

This counts the number of files starting with $dir, then adds one to that number and creates a new file.

davidgo
  • 73,366
0

Addendum to the other answers: If you need the dirs to sort correctly by name, you may also want to pad the new dir number (NUM) with leading zeros to a fixed length.

The following could be condensed onto one line or embedded in one of the other solutions.

NUM="00"$NUM                  ## Left zero pad with fixed length - 1 zeros 
NUM=${NUM:((${#NUM} - 3)):3}  ## left trim to fixed length (3 in this case)

This assumes that NUM starts out at least 1 digit long and will not exceed the fixed length. Adjust accordingly to your requirements.

Joe
  • 586
  • 6
  • 13