Bagaimana saya memberi tahu mkdir untuk mencoba membuat dir1, dan jika sudah ada buat dir2, dll, hingga menyentuh nama yang tidak ada?

13

Saya ingin membuat direktori dengan nomor di bagian akhir, ex "dir1", dan menambahkan nomor itu jika direktori sudah ada sampai menyentuh nama direktori yang tidak ada, dan saya perlu melakukan ini dalam satu baris di baris perintah Linux, sesuatu seperti:

mkdir --increment dir$

Bagaimana saya bisa melakukan itu?

Sejauh ini saya sudah mendapat ini:

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

Tapi itu hanya menggemakan nama dir berikutnya, saya membutuhkannya secara rekursif menjalankan perintah.

01AutoMonkey
sumber

Jawaban:

26

Ini adalah latihan sepele dalam penggunaan while:

n = 0
sementara! mkdir dir $ n
melakukan
    n = $ ((n +1))
selesai

Tetapi tentu saja tidak perlu banyak pemikiran untuk menyadari bahwa mekanisme sepele ini tidak memiliki skala yang baik.

Jadi, alih-alih menciptakan kembali roda dan harus mencukur semua sudut lagi, kita menciptakan direktori sementara yang unik dari templat yang sedikit berbeda:

name = $ (mktemp -d dirXXXXXXXXXXX)

JdeBP
sumber
Pencarian biner pada nomor tersebut mungkin cukup baik.
Thorbjørn Ravn Andersen
Ada beberapa sudut untuk dicukur dari tempat Anda memulai proses reinvention roda, tidak sedikit yang mengingat sistem file, mempertimbangkan keamanan, dan paralelisasi.
JdeBP
6

Jika Anda hanya ingin secara bertahap membuat direktori yang terdaftar dalam urutan yang benar, dapatkah saya merekomendasikan folder yang diberi nama berdasarkan tanggal saat ini?

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

Ini akan membuat direktori dengan nama-nama seperti dir-2014-03-02( YYYY-MM-DD, sehingga muncul dalam urutan abjad).

Jika Anda membuat lebih dari satu direktori per hari, Anda dapat menambahkan waktu saat ini ke nama file. Lihat man datebagaimana cara mengubah format output date.

IQAndreas
sumber
5

cari dirname "terbesar" terlebih dahulu, dapatkan nomor dan selisihnya:

last_dir=(printf "%s\n" dir* | sort -Vr | head -1)
num=$(last_dir#dir)
mkdir "dir$((num+1))"
glenn jackman
sumber
Ini adalah ide yang bagus, tetapi tidak mudah untuk dilumpuhkan.
Thorbjørn Ravn Andersen
Kecuali ada jutaan direktori, paralelisasi jelas merupakan optimasi prematur.
glenn jackman
Mengapa Anda perlu di printfsini? Bukankah echopekerjaan sederhana ?
Ruslan
Juga, saya akan menggunakan dir[0-9]*sebagai gantinya dir*.
Ruslan
1
Kamu salah paham. Saya berbicara tentang apakah skrip masuk akal untuk dijalankan berulang kali sekaligus (beberapa utas, banyak pengguna, dll.) Atau tidak.
Thorbjørn Ravn Andersen
2

Dengan asumsi direktori Anda selalu dimulai pada "dir1", dan bahwa tidak ada file bernama $ dir * (iE mereka semua direktori nomor berurutan), Anda dapat pergi dengan liner satu ini -

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

Ini menghitung jumlah file yang dimulai dengan $ dir, kemudian menambahkan satu ke nomor itu dan membuat file baru.

davidgo
sumber
0

Tambahan untuk jawaban lain: Jika Anda perlu dir untuk mengurutkan dengan benar berdasarkan nama, Anda mungkin juga ingin memasukkan nomor dir (NUM) baru dengan memimpin nol ke panjang tetap.

Berikut ini dapat diringkas ke satu baris atau disematkan di salah satu solusi lain.

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)

Ini mengasumsikan bahwa NUM dimulai setidaknya 1 digit panjang dan tidak akan melebihi panjang tetap. Sesuaikan dengan kebutuhan Anda.

Joe
sumber