Como eu crio diretórios com nomes após cada mês?

8

Eu gostaria de criar um nome de diretório para cada mês. Eu sei, depois de alguns jogando com o shell, que:

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

Então usei a expansão de chaves, echo {1..12}/01 e tentei xargs it:

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

Mas falha miseravelmente: / (depois eu gostaria de aplicar mkdir ). Como posso fazer isso?

    
por JammingThebBits 10.08.2018 / 13:49

6 respostas

17

Com -I , xargs obtém um argumento por linha em oposição ao padrão de um argumento por (sem delimitação em branco ou nova linha, possivelmente entre aspas) word sem -I (e implica -n ). Portanto, no seu exemplo date é chamado apenas uma vez com {} expandido para toda a saída de echo (que está em uma linha), menos a nova linha à direita.

Aqui você pode fazer (note que -d é uma extensão do GNU):

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

(note que não funcionará corretamente em locais onde abreviações de nomes de meses contenham espaços ou caracteres de aspas; com GNU xargs , você pode contornar isso usando xargs -d '\n' mkdir -- )

Agora, para obter a lista de abreviações mensais em sua localidade, consultar o local diretamente faria mais sentido:

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

(veja também locale -k LC_TIME para ver todos os dados de localidade na categoria LC_TIME ).

Ou nativamente em zsh :

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

Pelo menos nos sistemas GNU, em algumas localidades, as abreviações dos meses são preenchidas com largura fixa com espaços:

$ 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月

Você pode querer remover esse preenchimento.

Os espaços iniciais seriam removidos por xargs -I , mas não pelos que estão à direita. Com zsh :

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

Tente um loop?

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

Se você quiser criar um diretório para cada mês, eu faria algo como:

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

Em shells com expansão de chave e data aceitando entrada de DATAFILE, tente

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

e canalize para o shell se estiver satisfeito com o resultado.

    
por 10.08.2018 / 14:04
5

Seu comando não funciona, porque usando -I altera o delimitador de xargs:

-I replace-str
Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character.

Você pode adicionar -d " " a xargs para que funcione. Mas você nem precisa de -I{} no seu caso:

Tente isso,

echo {1..12}/01 | xargs -n1 date +%b -d | xargs mkdir
    
por 10.08.2018 / 14:03
3

Você tão perto.

O problema é que o echo está produzindo uma única linha 1/01 2/01 3/01 4/01 5/01 6/01 7/01 8/01 9/01 10/01 11/01 12/01 e que o xargs está usando o caractere de nova linha como um separador de campo (não o espaço).

A solução: Diga ao echo para colocar um espaço entre cada campo.

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

Inseri apenas \n no final do eco.

Em seguida, faça os diretórios adicionar |xargs mkdir

por exemplo.

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

    
por 10.08.2018 / 18:43
1

A maneira mais simples e robusta de fazer isso:

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

É uma lista estática de meses depois de tudo ...

Se você pretende usar o GNU date (aqui assumindo um $IFS e% GNUdate não modificados, como para o seu date -d ):

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