Як мені сказати mkdir спробувати створити dir1, і якщо він вже існує, створити dir2 тощо, поки він не знайде ім'я, яке не існує?


13

Я хочу створити каталог з номером в кінці, наприклад, "dir1" і збільшити це число, якщо каталог вже існує, поки він не потрапить до імені каталогу, яке не існує, і мені потрібно зробити це в одному рядку в командний рядок Linux, щось на кшталт:

mkdir --increment dir$

Як би я пішов робити це?

Поки що у мене є таке:

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

Але це просто перегукується з наступним іменем dir, мені це потрібно для рекурсивного виконання команди.

Відповіді:


26

Це банальна вправа у використанні while:

n = 0
поки! mkdir dir $ n
робити
    n = $ ((n + 1))
зроблено

Але, звичайно, не потрібно багато думок, щоб усвідомити, що цей тривіальний механізм не так добре масштабується.

Тож замість того, щоб винаходити колесо та знову змушувати голити всі кути, створюється унікальний тимчасовий каталог із шаблону дещо інакше:

name = $ (mktemp -d dirXXXXXXXXXXX)


Двійковий пошук за номером може бути досить хорошим.
Thorbjørn Ravn Andersen

Існує досить багато куточків, які потрібно відрізати від того, з чого ви починаєте процес відновлення колеса, не останнє з яких - це запам'ятовування файлової системи, врахування безпеки та паралелізації.
JdeBP

6

Якщо ви просто хочете поступово створювати каталоги, перелічені у правильному порядку, чи можу я замість цього порекомендувати папки, названі на основі поточної дати?

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

Він створить каталоги з іменами типу dir-2014-03-02( YYYY-MM-DDтак, щоб відображатися в алфавітному порядку).

Якщо ви створюєте більше одного каталогу в день, ви можете додати поточний час до імені файлу. Дивіться, man dateяк налаштувати вихідне форматування date.


5

спочатку знайдіть "найбільше" ім'я, отримайте число та приріст, який:

last_dir=(printf "%s\n" dir* | sort -Vr | head -1)
num=$(last_dir#dir)
mkdir "dir$((num+1))"

Це гарна ідея, але паралельно це не просто.
Thorbjørn Ravn Andersen

Якщо немає мільйонів каталогів, паралелізація, безумовно, передчасна оптимізація.
glenn jackman

Навіщо тобі printfтут потрібно ? Не буде простою echoроботою?
Руслан

Також я б використав dir[0-9]*замість цього dir*.
Руслан

1
Ви неправильно розумієте. Я говорю про те, чи розумний сценарій запускати кілька разів одночасно (кілька потоків, кілька користувачів тощо) чи ні.
Thorbjørn Ravn Andersen

2

Якщо припустити, що ваші каталоги завжди починаються з "dir1", і що немає файлів з назвою $ dir * (тобто всі вони мають каталоги з порядковим номером), ви можете піти з цього одного вкладиша -

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

При цьому підраховується кількість файлів, починаючи з $ dir, потім додається один до цього числа і створюється новий файл.


0

Додаток до інших відповідей: Якщо вам потрібно, щоб дріси правильно сортували за назвою, ви також можете встановити нове число dir (NUM) з провідними нулями на фіксовану довжину.

Наведені нижче можуть бути конденсовані на одній лінії або вбудовані в один з інших розчинів.

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)

Це передбачає, що NUM починається щонайменше з однієї цифри і не перевищує фіксовану довжину. Відповідно до своїх вимог.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.