すべての文字のディレクトリを再帰的に作成します


12

ディレクトリをからaまでラベル付けする必要があるような方法でディレクトリを作成したいと思いますz。これらの各ディレクトリ内に、サブディレクトリを作成してaaabなどのラベルを付ける必要があります。

したがって、たとえば、ディレクトリのm場合、私のサブディレクトリにはmambupto というラベルが付けられmzます。


3
-pもサブディレクトリを作成しているため、最初のmkdirは必要ありません。また、絶対パスを使用する場合は、cdコマンドは必要ありません。それ以外の場合は、動作が良好で、変数が宣言されているなどです。MichaelHomerのバージョンは短く、パフォーマンスが向上している可能性がありますが、このような単純なタスクでは十分です。

1
当時、より多くのtermininfoエントリがあり、bash {a..z}構文はなかったので/usr/share/terminfo、[az]でリストし、その出力を使用しました。Linuxはその数がかなり少ないため、以前はすべての大文字と小文字、および数字のエントリでした。
スキーマ14

回答:


19

試してください:

for x in {a..z} ; do mkdir -p $x/${x}{a..z} ; done

bashは拡大するXXX{a..z}に出てXXXaXXXbなど。内側のループは必要ありません。

その後:

$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
$ ls m
ma  mc  me  mg  mi  mk  mm  mo  mq  ms  mu  mw  my
mb  md  mf  mh  mj  ml  mn  mp  mr  mt  mv  mx  mz

7

だから、bashのアルファベット拡張のことで、これは動作します:

set {a..z}
for a do printf "./$a/$a%s\n" "$@"
done | xargs mkdir -p

また、最初の行にアルファベットを1回入力するだけで、同じ概念がどのシェルにも移植可能になります。入力したくない場合に設定行に到達する方法は他にもあります。

seq -sP32P 97 123|dc
a b c d e f g h i j k l m n o p q r s t u v w x y z 

...たとえば、ASCIIロケールで動作します。そのため、必要な引数の個別のリストをset $(seq -sP32P 97 123|dc)取得するコマンドまたは他のコマンドを実行でき$IFSますが、そのbashことを使用するか入力する方がよいでしょう。

とにかく、私はそれが私がそれをする方法だと思うのは、それmkdirが必要なだけ頻繁に呼び出すからです。

そして、それがどのように機能するを示すために、小さなセットの小さなデバッグ出力を以下に示します。

sh -cx 'for n do printf "./$n/$n%s\n" "$@"; done|cat' -- arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg1/arg1%s\n' arg1 arg2 arg3
+ cat
+ for n in '"$@"'
+ printf './arg2/arg2%s\n' arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg3/arg3%s\n' arg1 arg2 arg3
./arg1/arg1arg1
./arg1/arg1arg2
./arg1/arg1arg3
./arg2/arg2arg1
./arg2/arg2arg2
./arg2/arg2arg3
./arg3/arg3arg1
./arg3/arg3arg2
./arg3/arg3arg3

ご覧のように、forループは位置パラメータ配列インデックスごとに1回だけループします。ここshでは、呼び出し時にパラメータを渡すことで設定しますset ${positionals}。ただしprintf、各反復の引数リストで同じ配列を受け取り、その各引数にフォーマット文字列を適用するため、不必要な再帰なしで再帰の外観を取得できます。

そして、同じ方法でパイプを介してループのdone|commandすべてforの出力をストリームに追加すると、すべてがdone >fileファイルにストリームされます- for...done構造全体に対して出力ファイルを一度だけ開いたり閉じたりします。


3

ここから、このようなスクリプトを作成することになりました。ただし、エレガントなソリューションが得られた場合は、回答として受け入れます。

for x in {a..z}
do
    mkdir -p /home/ramesh/$x
    cd /home/ramesh/$x
    for y in {a..z}
    do
        mkdir -p /home/ramesh/$x/$x$y
    done
done

+1、良い質問と良い答え:)
ニダル14

@Networker、これよりもかなり良い解決策があると確信しています。この回答と同様の仕事をする専門家の回答を待っていますが、もっとクールに見えます:)
Ramesh 14

厳密に言えば、変数の値がどうなるかを知っているときは(それは単純な文字列です)必要はありませんが、変数を引用する習慣を身に付けることは良い考えです。あなたは使うことができ/home/ramesh/"$x"/"$x$y"/home/ramesh/"$x/$x$y"または"/home/ramesh/$x/$x$y"それらはすべて同等です- 。
スコット14

1

Perl

perl -MFile::Path=make_path -e '
    make_path(map { $l=$_; map { "$l/$l$_" } a..z } a..z)
'

File::Path以来のコアモジュールですPerl 5.001

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.