user11532787
user11532787

Reputation:

Bash - create a nonexistent directory

I have catalogs

site_2021-11-09_0
site_2021-11-09_1
site_2021-11-09_2
site_2021-11-09_3
site_2021-11-09_4
site_2021-11-09_5
site_2021-11-09_6

I need to add next directory that does not exist, which is site_2021-11-09_7. I need to write a script on loops. How can this be done?

I currently have

#!/bin/bash

date="$(date +%F)"
site="site"

i="0"

while [ ! -d ${site}_${date}_$i ]
do
    echo ${site}_${date}_$i
    mkdir ${site}_${date}_$i
    i=$(( $i + 1))
done

but it doesn't work. If no directories exist, it works forever. If there is directory site_2021-11-09_0, it doesn't work at all. How to understand it logically?

Upvotes: 1

Views: 3591

Answers (4)

kvantour
kvantour

Reputation: 26491

Here are some ways to achieve what you want:

i=0; while [ -d "${site}_${date}_$i" ]; do ((i++)); done; mkdir -v "${site}_${date}_$i"
i=0; while ! mkdir "${site}_${date}_$i"; do ((i++)); done
i=0; for d in "${site}_${date}_"*; do ((i=i>${d##*_}:i?${d##*_})); done; mkdir -v "${site}_${date}_$((i+1))"

when your directories are sortable, that is only when the index counter has a fixed amount of digits, (e.g. ${site}_${date}_001, ${site}_${date}_002 , ... , ${site}_${date}_078), you can make use of the lexicographical ordering of globs

dirlist=( "${site}_${date}"_* )
mkdir -v "${site}_${date}_$(printf "%.3d" "$((10#${dirlist[-1]##*_}+1))")"

Upvotes: 5

dan
dan

Reputation: 5241

You can use this bash script:

#!/bin/bash -e

prefix=${1:?no site given}_$(date +%F)_

while [[ -d "$prefix$((i++))" ]]; do :; done

mkdir "$prefix$((i-1))"

Call like ./mk-site-dir sitename.

You can hardcode sitename if you want.

Upvotes: 1

2e0byo
2e0byo

Reputation: 5954

As @kvantour says, you currently make a directory so long as it doesn't exist, and then increment i. Thus in any empty directory it will run indefinitely; whereas if there is a matching dir after 0 your code will make all the directories before it and then stop. What you want is probably:

while [ -d ${site}_${date}_$i ]
do
    i=$(( $i + 1))
done

mkdir ${site}_${date}_$i

I.e. get the first directory which doesn't exist, and then make it.

Upvotes: 0

phoney_badger
phoney_badger

Reputation: 533

Presently your code is doing

while (directory does not exist)
    do stuff

but your first directory site_2021-11-09_0 does indeed exist. So the condition inside the while is never satisfied and so the program doesn't run. You can make a slight modification to your code by changing the logic to keep running as long as the directory exists and then make a new directory with the next index when the loop is broken

#! /bin/sh

date="$(date +%F)"
site="site"

i="0"

while [ -d ${site}_${date}_$i ]
do
    echo ${site}_${date}_$i
    i=$(( $i + 1))
done
mkdir ${site}_${date}_$i

Upvotes: 2

Related Questions