Mkdir kullanarak çok sayıda dizin oluşturma


14

Kullanarak birçok dizin oluşturmak istiyorum mkdir. Her dizin adı bir önek (dize) ve bir dizin (bir tamsayı) içerecektir. Önek "s" ve indeksler 1 ila 50 arasında olmasını istiyorum varsayalım. Bu, başlıklı dizinler oluşturmak istiyorum anlamına gelir:

s1,, s2... s49,,s50

Bunu kullanarak otomatik olarak yapmanın bir yolu var mı mkdir? Zaman ayırdığınız için teşekkürler.


2
Hangi kabuğu kullanıyorsun?
Francesco Turco

@FrancescoTurco kullanıyorum bash. Zaman ayırdığınız için teşekkür ederim!
Andrew

3
Bilginize, ben bulmak çok daha yararlı olduğu gibi, sabit genişlikli endeks kullanmak: s01, s02, ..., s49, s50. Sabit genişlikli indeksler kullansaydım /bin/lsneredeyse her zaman istediğim sıralamayı üretir.
Rob

Yanıtlar:


32

Bunu bir kabuk komut dosyası ile yapabilirsiniz.

Saf sh - bu POSIX öncesi bourne mermilerinde bile çalışır:

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

Çok sayıda dizin oluşturmak istiyorsanız, komut dosyasını tek bir çağrıya indirgeyerek mkdir, test ve aritmetik için kabuk yerleşiklerini kullanarak daha hızlı yapabilirsiniz . Bunun gibi:

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 veya bash bunu çok daha kolay hale getiriyor, ancak bunun yerleşik mkdirolmayan ve diğer kabuklarda çalışmayabileceğini belirtmeliyim. Daha büyük durumlarda, bir komuta iletilebilecek bağımsız değişkenlerin sayısı veya toplam boyutu üzerindeki sınırlardan da etkilenebilir.

mkdir s{1..50}

3
+1 Bu harika! Bir şey hakkında nitpick yapmalıyım: n=$(( n + 1 ))kesinlikle POSIX olurdu ve size bir alt kabuğa mal olmazdı.
kojiro

@rahmu [[anahtar kelimesi POSIX değil. (Bunun birçok modern [
mermide

@ kojiro: [[benim ksh88(önceki yırtıcı) üzerinde çalışır, bu bashyüzden POSIX olduğunu varsaydım. POSIX spesifikasyonunda bundan bahsetmedim, bu yüzden haklı olduğuna inanıyorum. Bilgi için teşekkürler!
rahmu

Aritmetik genişletme kullanarak bir sürüm eklemeyi düşündüm, ancak "saf sh" POSIX öncesi sürümlerde de çalışacak şeyler ile sınırlandırmak istedim. Ben de aynı nedenle seq bahsetmedim - eğer seq varsa muhtemelen bash var. Döngü örneği, daha fazla sayıda dizin için argüman sınırlarını atlamak için de iyidir, bu da for i in {range}gelişmiş kabukların kullanıcıları için bir yer olduğu anlamına gelir .
Random832

Sonunda zsh ipucu şaşırtıcı, bu beni çok zaman kazandırdı!
Jase

33
  • Bir

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

    mkdir s{1..50}

    Bu seçenek bash , zsh ve ksh93 olarak çalışır

  • Üç

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

4
Neden ikiden bir tanesini kullandın?
Kevin

7
$isadece bir dizin yapmaktan daha fazlasını yapmak isteyebilirsiniz mkdir s$i ; echo $i > s$i/$i. Ayrıca, biri bash'de for döngüsü kullanmanın güzel, basit bir örneğidir ... böyle bir sitede acemi bir kullanıcının görmesi ve "güzel, bunu yapabileceğinizi fark etmedim. "---> aydınlanma.
cas

1
@rahmu Bash / Zsh'da bulunan bir özellik (muhtemelen ksh93 de). İndirmeye gerek yok.
helpermethod

3
@rahmu: Bence sadece jhonathan'ın cevabı problemi OP'nin kabuğuyla (bash) düzeltiyorsa, başkalarıyla değil.
Francesco Turco

4
@Kevin elli için bir sorun olmayacak olsa da, beş yüz dizininiz varsa, argüman sınırları hakkında endişelenebilirsiniz.
Random832

10

Burada bir sürü karmaşık cevap var, ama bash bunu gerçekten kolaylaştırıyor. Elbette, saf POSIX çözümü işe yarıyor, ama neden kullandığınız bashkabuğun avantajından yararlanmıyorsunuz ? Brace genişlemesi ile bunu kolayca yapabilirsiniz :

% 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

5

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

veya sıfır dolgulu sayılar istiyorsanız (sıralama için daha iyi olur):

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

veya:

mkdir s$(seq -s ' s' -w 1 50)- 's' dizesinin hemen öncesine dikkat edin $(), onsuz ilk dizin 's01' yerine '01' olacaktır.

ve sonunda: mkdir $(printf "s%02i " $(seq 1 50))

seq GNU Coreutils'ten

garip bir şekilde, seq's --formatveya -fseçenek sadece printf'in kayan nokta çift tiplerine izin verir (f ve g gibi. Neden olduğuna dair hiçbir fikrim yok. printf(3)Tamsayı (d, i), sekizli (o, U) veya altıgen (x, X) gibi diğer sayısal türleri de desteklemesi iyi olurdu .

Her neyse, 0 ondalık hassasiyete sahip %.0fveya %02.0fbu amaçla bir tamsayıya yeterince yakın olan çift biçim .

$ seq --help
Kullanım: seq [SEÇENEK] ... SON
  veya: seq [SEÇENEK] ... BİRİNCİ SON
  veya: seq [SEÇENEK] ... İLK İNCELEME SON
INCREMENT adımlarında FIRST ile LAST arasındaki sayıları yazdırın.

  -f, --format = FORMAT printf stili kayan noktalı FORMAT kullan
  -s, --separator = STRING, sayıları ayırmak için STRING kullanır (varsayılan: \ n)
  -w, - eşit genişlik önde gelen sıfırlarla dolgu yaparak genişliği eşitler
      --help bu yardımı göster ve çık
      - sürüm çıktı sürümü bilgileri ve çıkış

FIRST veya INCREMENT belirtilmezse, varsayılan değer 1'dir.
LAST FIRST değerinden daha küçük olsa bile atlanan INCREMENT varsayılanı 1'dir.
İLK, İNCELEME ve SON kayan nokta değerleri olarak yorumlanır.
İLK SONU, SON'dan küçükse INCREMENT genellikle pozitiftir ve
FIRST, LAST değerinden büyükse INCREMENT genellikle negatiftir.
FORMAT, "double" türünde bir bağımsız değişken yazdırmak için uygun olmalıdır;
FIRST, INCREMENT ve LAST sabit nokta ise varsayılan olarak% .PRECf olarak ayarlanır
maksimum hassasiyet PREC ile ondalık sayılar ve aksi takdirde% g.

Ayrıca bkz: http://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html


{1,50}veya {01,50}(sıfır doldurma için) çok daha kolay ve daha anlaşılır.
Kevin

1
true ... sh yerine bash kullanıyorsanız. bu yüzden @ Random832'nin cevabını onayladım. bu iyi bir cevap. seq kullanmak da yararlı bir cevaptır.
cas

4

Sadece farklı olmak için, özyineleme kullanan bir POSIX sh çözümü:

makedirs() {
  [ "$1" -gt 0 ] || return
  mkdir "s$1"
  makedirs $(( $1 - 1 ))
}
$ makedirs 9
$ ls
s1  s2  s3  s4  s5  s6  s7  s8  s9
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.