Membuat banyak direktori menggunakan mkdir

13

Saya ingin membuat banyak direktori menggunakan mkdir. Setiap nama direktori akan terdiri dari awalan (string) dan indeks (integer). Misalkan saya ingin awalan menjadi "s" dan indeks berkisar dari 1 hingga 50. Ini berarti bahwa saya ingin membuat direktori berjudul:

s1,, s2... s49,,s50

Apakah ada cara untuk melakukan ini secara otomatis menggunakan mkdir? Terima kasih atas waktunya.

Andrew
sumber
2
Shell mana yang Anda gunakan?
Francesco Turco
@ FrancescoTurco saya gunakan bash. Terima kasih atas waktu Anda!
Andrew
3
FYI, saya merasa jauh lebih berguna untuk menggunakan indeks fixed-width, seperti: s01, s02, ..., s49, s50. Jika saya menggunakan indeks lebar tetap, /bin/lshampir selalu menghasilkan pesanan yang saya inginkan.
Rob

Jawaban:

31

Anda dapat melakukan ini dengan skrip shell.

Pure sh - ini akan bekerja bahkan pada shell bourne pra-POSIX:

n=1;
max=50;
while [ "$n" -le "$max" ]; do
  mkdir "s$n"
  n=`expr "$n" + 1`;
done

Jika Anda ingin membuat banyak direktori, Anda dapat membuat skrip lebih cepat dengan menguranginya menjadi satu panggilan mkdirsekaligus menggunakan shell bawaan untuk pengujian dan aritmatika. Seperti ini:

n=1
max=50
set -- # this sets $@ [the argv array] to an empty list.

while [ "$n" -le "$max" ]; do
    set -- "$@" "s$n" # this adds s$n to the end of $@
    n=$(( $n + 1 ));
done 

mkdir "$@"

Zsh, ksh93 atau bash membuat ini lebih mudah, tapi saya harus menunjukkan ini tidak dibangun ke dalam mkdirdan mungkin tidak berfungsi di shell lain. Untuk kasus yang lebih besar, ini juga dapat dipengaruhi oleh batasan jumlah atau ukuran total argumen yang dapat diteruskan ke perintah.

mkdir s{1..50}
Random832
sumber
3
+1 Ini luar biasa! Tapi saya harus tahu satu hal: n=$(( n + 1 ))akan sama kerasnya dengan POSIX dan tidak akan dikenakan biaya sedikitpun.
kojiro
@rahmu [[kata kuncinya bukan POSIX. (Belum lagi itu [ adalah shell builtin di banyak shell modern.)
kojiro
@ Kojiro: [[bekerja pada saya ksh88(yang mendahului bash) jadi saya berasumsi itu POSIX. Saya tidak dapat menemukan menyebutkannya dalam spesifikasi POSIX jadi saya yakin Anda benar. Terimakasih atas infonya!
rahmu
Saya berpikir tentang menambahkan versi menggunakan ekspansi aritmatika, tetapi ingin membatasi "sh murni" untuk hal-hal yang akan bekerja pada versi pra-POSIX juga. Saya juga tidak menyebutkan seq untuk alasan yang sama - jika Anda memiliki seq Anda mungkin memiliki bash. Contoh loop juga baik untuk melewati batas argumen untuk sejumlah besar direktori, yang juga berarti ada tempat for i in {range}bagi pengguna shell canggih.
Random832
Petunjuk zsh pada akhirnya luar biasa, itu menyelamatkan saya begitu banyak waktu!
Jase
33
  • Satu

    for i in {1..50}; do
      mkdir s"$i"
    done
  • Dua

    mkdir s{1..50}

    Opsi ini berfungsi di bash , zsh dan ksh93

  • Tiga

    mkdir $(printf "s%02i " $(seq 1 50))
Jhonathan
sumber
4
Mengapa Anda menggunakan satu dari dua?
Kevin
7
Anda mungkin ingin melakukan lebih $idari sekedar membuat direktori misalnya mkdir s$i ; echo $i > s$i/$i. Juga, One adalah contoh sederhana yang bagus untuk menggunakan for for in bash ... di situs seperti ini sama sekali tidak mungkin bagi pengguna pemula untuk melihatnya dan berpikir "bagus, saya tidak sadar Anda bisa melakukan itu "---> pencerahan.
cas
1
@rahmu Ini adalah fitur yang ditemukan di Bash / Zsh (mungkin ksh93 juga). Tidak perlu downvote.
helpermethod
3
@rahmu: Saya pikir orang hanya harus mempertimbangkan jika jawaban jhonathan memperbaiki masalah dengan shell OP (bash), tidak harus dengan yang lain.
Francesco Turco
4
@Kevin sementara itu tidak akan menjadi masalah bagi lima puluh, jika Anda punya lima ratus direktori untuk membuat Anda mungkin khawatir tentang batasan argumen.
Random832
10

Banyak jawaban rumit di sini, tetapi bash membuatnya sangat mudah. Tentu, solusi POSIX murni berfungsi, tetapi mengapa tidak mengambil keuntungan dari bashshell yang Anda gunakan, bagaimanapun? Anda dapat melakukan ini dengan mudah dengan ekspansi brace :

% mkdir -v s{1..10} && ls -1d s{1..10}                                   (09-24 17:37)
mkdir: created directory `s1'
mkdir: created directory `s2'
mkdir: created directory `s3'
mkdir: created directory `s4'
mkdir: created directory `s5'
mkdir: created directory `s6'
mkdir: created directory `s7'
mkdir: created directory `s8'
mkdir: created directory `s9'
mkdir: created directory `s10'
s1
s10
s2
s3
s4
s5
s6
s7
s8
s9
laebshade
sumber
5

mkdir $(seq --format 's%.0f' 1 50)

atau jika Anda menginginkan angka nol-empuk (yang akan lebih baik untuk menyortir):

mkdir $(seq --format 's%02.0f' 1 50)

atau:

mkdir s$(seq -s ' s' -w 1 50)- perhatikan string 's' tepat sebelum $(), tanpa itu direktori pertama yang dibuat hanya '01' daripada 's01'

dan akhirnya: mkdir $(printf "s%02i " $(seq 1 50))

seq berasal dari GNU Coreutils

anehnya, seq's --formatatau -fopsi hanya memungkinkan tipe ganda floating point printf (seperti f dan g. juga format hex floating point aneh yang saya tidak pernah menemukan gunanya). Saya tidak tahu kenapa. Akan lebih baik jika juga mendukung printf(3)tipe numerik lainnya seperti integer (d, i), oktal (o, U) atau hex (x, X).

Bagaimanapun, format ganda dengan 0 desimal presisi suka %.0fatau %02.0fcukup dekat dengan integer untuk tujuan ini.

$ seq --help
Penggunaan: seq [OPSI] ... TERAKHIR
  atau: seq [OPSI] ... TERAKHIR TERAKHIR
  atau: seq [OPTION] ... INCREMENT PERTAMA TERAKHIR
Cetak angka dari PERTAMA ke TERAKHIR, dalam langkah INCREMENT.

  -f, --format = FORMAT menggunakan FORMAT floating-point printf style
  -s, --separator = STRING gunakan STRING untuk memisahkan angka (default: \ n)
  -w, --equal-equalize lebar dengan melapisi dengan nol terkemuka
      --help tampilkan bantuan ini dan keluar
      --informasi versi keluaran versi dan keluar

Jika FIRST atau INCREMENT dihilangkan, defaultnya adalah 1. Yaitu, an
INCREMENT yang dihapus dihilangkan menjadi 1 walaupun LAST lebih kecil dari PERTAMA.
FIRST, INCREMENT, dan LAST diinterpretasikan sebagai nilai floating point.
PENINGKATAN biasanya positif jika PERTAMA lebih kecil dari TERAKHIR, dan
INCREMENT biasanya negatif jika FIRST lebih besar dari LAST.
FORMAT harus sesuai untuk mencetak satu argumen bertipe `ganda ';
defaultnya adalah% .PRECf jika FIRST, INCREMENT, dan LAST semuanya adalah titik tetap
angka desimal dengan presisi PREC maksimum, dan ke% g sebaliknya.

Lihat juga: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html

cas
sumber
{1,50}atau {01,50}(untuk zero-padding) jauh lebih mudah dan lebih mudah dimengerti.
Kevin
1
true ... jika Anda menggunakan bash daripada sh. itu sebabnya saya membenarkan jawaban @ Random832. itu jawaban yang bagus. menggunakan seq juga merupakan jawaban yang bermanfaat.
cas
4

Untuk menjadi berbeda, inilah solusi sh POSIX yang menggunakan rekursi:

makedirs() {
  [ "$1" -gt 0 ] || return
  mkdir "s$1"
  makedirs $(( $1 - 1 ))
}
$ makedirs 9
$ ls
s1  s2  s3  s4  s5  s6  s7  s8  s9
kojiro
sumber