Bagaimana cara membuat nama direktori setelah setiap bulan?

8

Saya ingin membuat nama direktori untuk setiap bulan. Saya tahu, setelah beberapa bermain dengan shell, bahwa:

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

Jadi saya telah menggunakan ekspansi brace, echo {1..12}/01dan mencobanya xargs:

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

Tetapi gagal total: / (setelah itu saya ingin mendaftar mkdir). Bagaimana saya bisa melakukan ini?

JammingThebBits
sumber
4
Anda sepertinya terlalu memprogram ini. Jika ada alasan, itu akan membantu jika Anda menjelaskan mengapa Anda tidak hanya menulis 12 baris, "mkdir" Jan "; mkdir" Feb "; ...". Jika Anda perlu melakukannya berkali-kali, masukkan kode dalam suatu fungsi, dan panggil sesuai kebutuhan.
jamesqf
4
Mengapa Anda memberi nama direktori Anda dengan nama bulan, bukan angka 01-12? Pasti aneh jika mereka lsmenyuntingnya dalam urutan abjad (Apr, Agu, Dec, Feb, Jan, Jul, Jun, Mar, May, Nov, Oct, Sep).
user1024
2
@ jamesqf Mengapa Anda melakukan itu ketika Anda bisa melakukannya mkdir january february [...]? Kecuali Anda benar-benar perlu membuatnya secara terpisah, tidak perlu melakukannya seperti yang Anda sarankan.
Pryftan
@ user1024 Saya biasanya setuju dengan Anda, tetapi saya memiliki satu kasus penggunaan nama bulan (huruf kecil); di lain saya punya 01january dll. Siapa yang tahu? Ada banyak alasan mengapa hal itu mungkin atau mungkin lebih baik. (Tapi ya - jika menyortir adalah masalah ...)
Pryftan
@Pryftan: Hanya preferensi pribadi untuk baris yang lebih pendek :-) Juga, jika saya kemudian ingin mengubah ke misalnya "01Jan", lebih mudah di editor saya untuk melakukan "c / / 01/12 1" daripada melakukan perubahan pada satu baris.
jamesqf

Jawaban:

17

Dengan -I, xargsdapatkan satu argumen per baris sebagai lawan dari default satu argumen per (kosong atau baris baru dibatasi, mungkin dikutip) kata tanpa -I(dan menyiratkan -n). Jadi, dalam contoh Anda datedipanggil hanya sekali dengan {}diperluas ke seluruh output echo(yang ada di satu baris), minus baris baru.

Di sini Anda dapat melakukannya (perhatikan bahwa itu -dadalah ekstensi GNU):

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

(perhatikan bahwa itu tidak akan berfungsi dengan benar di lokal di mana singkatan nama bulan berisi spasi atau karakter kutipan; dengan GNU xargs, Anda dapat mengatasinya dengan menggunakan xargs -d '\n' mkdir --)

Sekarang, untuk mendapatkan daftar singkatan bulan di lokal Anda, menanyakan langsung ke lokal akan lebih masuk akal:

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

(lihat juga locale -k LC_TIMEuntuk melihat semua data lokal dalam LC_TIMEkategori).

Atau secara native di zsh:

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

Setidaknya pada sistem GNU, di beberapa lokal, singkatan bulan diisi hingga lebar tetap dengan spasi:

$ 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

Anda mungkin ingin menghapus lapisan itu.

Ruang utama akan dihapus oleh xargs -I, tetapi bukan yang tertinggal. Dengan zsh:

zmodload zsh/langinfo
set -o extendedglob
mkdir -- ${${${(v)langinfo[(I)ABMON*]}##[[:space:]]#}%%[[:space:]]#}
Stéphane Chazelas
sumber
Bagus! Tidak tahu locale abmon.
maulinglawns
Bagus jawaban, tapi tl; dr: IFS=';'; set -o noglob; mkdir -- $(locale abmon). ;)
Skippy le Grand Gourou
9

Coba satu putaran?

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

Jika Anda ingin membuat direktori untuk setiap bulan, saya akan melakukan sesuatu seperti:

for m in {1..12}; do newdir=$(date -d "$m"/01 +%b); mkdir "$newdir"; done
undang-undang
sumber
Perhatikan itu {1..12}adalah bashism. Untuk cangkang POSIX, gunakan for m in $(seq 1 12)...(meskipun perhatikan bahwa seqitu sendiri tidak diamanatkan oleh POSIX)
Radovan Garabík
2
@ RadovanGarabík, secara teknis, {1..12}adalah zshism, disalin kemudian oleh ksh93, bash, dan beberapa shell lainnya.
Stéphane Chazelas
5

Dalam shell dengan ekspansi brace, dan tanggal menerima input DATAFILE, coba

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

dan pipa ke shell jika senang dengan hasilnya.

RudiC
sumber
5

Perintah Anda tidak berfungsi, karena menggunakan -Iperubahan pembatas xargs:

-I replace-str
Mengganti kemunculan replace-str di argumen-awal dengan nama yang dibaca dari input standar. Juga, blanko tanda kutip tidak menghentikan item input; sebaliknya pemisah adalah karakter baris baru.

Anda dapat menambahkan -d " "ke xargs untuk membuatnya berfungsi. Tetapi Anda bahkan tidak perlu -I{}dalam kasus Anda:

Coba ini,

echo {1..12}/01 | xargs -n1 date +%b -d | xargs mkdir
pLumo
sumber
1
Perhatikan bahwa untuk GNU datemenerima opsi setelah argumen non-opsi seperti itu, tidak boleh ada POSIXLY_CORRECTvariabel di lingkungan.
Stéphane Chazelas
3

Anda di mana begitu dekat.

Masalahnya adalah bahwa gema menghasilkan satu baris 1/01 2/01 3/01 4/01 5/01 6/01 7/01 8/01 9/01 10/01 11/01 12/01, dan xargs menggunakan karakter baris baru sebagai pemisah bidang (bukan spasi).

Solusinya: Beri tahu gema untuk memberi spasi di antara setiap bidang.

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

Saya hanya menyisipkan \\ndi akhir gema.

Lalu untuk membuat direktori tambah |xargs mkdir

misalnya

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

ctrl-alt-delor
sumber
1

Cara paling sederhana dan paling kuat untuk melakukan ini:

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

Bagaimanapun, ini adalah daftar statis bulan ...

Jika Anda bermaksud menggunakan GNU date(di sini dengan asumsi $IFSGNU yang tidak dimodifikasi dan dateseperti untuk Anda date -d):

mkdir $( printf '%s\n' {1..12}/01 | date -f - +%b )
Kusalananda
sumber
2
Kecuali bahwa itu tidak membuat singkatan nama bulan dalam bahasa pengguna.
Stéphane Chazelas
@ StéphaneChazelas Kecuali mereka orang Swedia, seperti saya :-)
Kusalananda