毎月の名前のディレクトリを作成するにはどうすればよいですか?


8

毎月ディレクトリ名を作成したいと思います。シェルで遊んだ後、次のことがわかります。

date -d 1/01 +%b # Gives Jan
date -d 2/01 +%b # Gives Feb
.
date -d 12/01 +%b # Gives Dec

だから私はブレース展開を使用して、echo {1..12}/01それを試してみましxargsた:

echo {1..12}/01 | xargs -n 1 -I {} date -d {} +%b

しかし、それは惨めに失敗します:/(後で適用したいと思いますmkdir)。これどうやってするの?


4
あなたはこれをオーバープログラミングしているようです。理由がある場合は、「mkdir "Jan"; mkdir "Feb"; ...」という12行を単に記述しない理由を説明すると役立つでしょう。複数回行う必要がある場合は、コードを関数に入れ、必要に応じて呼び出します。
jamesqf 2018

4
01〜12の数字ではなく、月の名前でディレクトリに名前を付けるのはなぜですか。lsアルファベット順(4月、8月、12月、2月、1月、7月、6月、3月、5月、11月、10月、9月)に編集するのは厄介です。
user1024

2
@jamesqf単純にできるのに、なぜそうするのでしょうmkdir january february [...]か。実際に個別に作成する必要がない限り、提案した方法で作成する必要はありません。
プリフタン

@ user1024私は通常あなたに同意しますが、私は1つのユースケースで月の名前(小文字)を持っています。別のものでは01januaryなどがあります。それが何らかの形で優れている、または優れている理由は数多くあります。(しかし、はい-並べ替えが問題の場合...)
Pryftan

@Pryftan:短い行の個人的な好みのみ:-)また、後で「01Jan」などに変更したい場合は、編集者が「c / / 01/12 1」を実行するよりも「c / / 01/12 1」を実行する方が簡単です。 1行。
jamesqf 2018

回答:


17

を使用すると-Ixargs単語なしの-I(および空白で区切られた、引用符で囲まれている可能性がある)ワードごとのデフォルトの引数とは対照的に、行ごとに1つの引数を取得します(およびを意味します-n)。したがって、あなたの例でdateは、最後の改行を除いた(1行にある)の{}出力全体に展開されて1回だけ呼び出されechoます。

ここであなたがすることができます(それ-dはGNU拡張であることに注意してください):

printf '%s\n' {1..12}/01 | xargs -I {} date -d {} +%b | xargs mkdir --

(月の名前の省略形にスペースまたは引用符が含まれているロケールでは正しく機能しないことに注意してください。GNU xargsでは、を使用して回避できますxargs -d '\n' mkdir --

ここで、ロケールの月の省略形のリストを取得するには、ロケールを直接クエリする方が理にかなっています。

(IFS=';'; set -o noglob; mkdir -- $(locale abmon))

(カテゴリlocale -k LC_TIME内のすべてのロケールデータを表示する場合も参照してくださいLC_TIME)。

またはネイティブでzsh

zmodload zsh/langinfo
mkdir -- ${(v)langinfo[(I)ABMON_*]}

少なくともGNUシステムでは、一部のロケールでは、月の省略形が固定幅になるようにスペースで埋め込まれます。

$ LC_ALL=et_EE.UTF-8 locale title abmon
Estonian locale for Estonia
jaan ;veebr;märts;apr  ;mai  ;juuni;juuli;aug  ;sept ;okt  ;nov  ;dets
$ LC_ALL=zh_TW.UTF-8 locale title abmon
Chinese locale for Taiwan R.O.C.
 1月; 2月; 3月; 4月; 5月; 6月; 7月; 8月; 9月;10月;11月;12

そのパディングを削除することができます。

先頭のスペースはによって削除されますがxargs -I、末尾のスペースは削除されません。とzsh

zmodload zsh/langinfo
set -o extendedglob
mkdir -- ${${${(v)langinfo[(I)ABMON*]}##[[:space:]]#}%%[[:space:]]#}

いいね!について知りませんでしたlocale abmon
maulinglawns 2018

ニースの答えが、TL; DR: IFS=';'; set -o noglob; mkdir -- $(locale abmon)。;)
Skippy le Grand Gourou

9

ループしてみませんか?

$ for m in {1..12}; do
> date -d "$m"/01 +%b
> done
jan
feb
mar
apr
maj
jun
jul
aug
sep
okt
nov
dec

毎月ディレクトリを作成したい場合は、次のようにします。

for m in {1..12}; do newdir=$(date -d "$m"/01 +%b); mkdir "$newdir"; done

これ{1..12}はバシズムです。POSIXシェルの場合はfor m in $(seq 1 12)...seqそれ自体を使用します(ただし、POSIX 自体では必須ではありません)
RadovanGarabíkAug

2
@RadovanGarabíkは、技術的に{1..12}はzshismであり、後でksh93、bashおよびその他のいくつかのシェルによってコピーされます。
ステファンChazelas

5

ブレース展開のシェルで、DATAFILE入力を受け入れる日付で、

echo {01..12}/01$'\n' | date -f- +"mkdir %b"

結果に満足したら、シェルにパイプします。


5

-Ixargsの区切り文字を変更するため、コマンドは機能しません。

-I replace-str
initial-arguments内のreplace-strの出現箇所を標準入力から読み取った名前に置き換えます。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字です。

-d " "xargsに追加して機能させることができます。しかし、あなたは-I{}あなたの場合でも必要ではありません:

これを試して、

echo {1..12}/01 | xargs -n1 date +%b -d | xargs mkdir

1
GNU dateがそのような非オプション引数の後にオプションを受け入れるためにPOSIXLY_CORRECTは、環境内に変数があってはならないことに 注意してください。
ステファンChazelas

3

あなたはとても近くにいます。

問題は、echoが単一行を生成し、1/01 2/01 3/01 4/01 5/01 6/01 7/01 8/01 9/01 10/01 11/01 12/01xargsが改行文字をフィールド区切り文字(スペースではない)として使用していることです。

解決策:各フィールドの間にスペースを入れるようにエコーに伝えます。

echo -e {1..12}/01\\n | xargs -n 1 -I {} date -d {} +%b

\\nエコーの終わりに挿入しただけです。

次に、ディレクトリを追加するには |xargs mkdir

例えば

echo -e {1..12}/01\\n | xargs -n 1 -I {} date -d {} +%b | xargs mkdir


1

これを行う最も簡単で最も堅牢な方法:

mkdir jan feb mar apr maj jun jul aug sep okt nov dec

結局のところ、これは月の静的リストです...

GNUを使用することに熱心な場合date(ここでは、変更されていない$IFSGNU dateライクを想定していますdate -d):

mkdir $( printf '%s\n' {1..12}/01 | date -f - +%b )

2
ただし、ユーザーの言語で月名を省略しない点が異なります。
ステファンChazelas

@StéphaneChazelas私のようにスウェーデン人でない限り:-)
Kusalananda
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.