Liste aniversários na ordem em que eles virão hoje

4

Eu tenho um arquivo de texto contendo aniversários:

1/23 Horace
3/1 Taraneh
7/14 Valerian
11/31 Carmen

Eu quero exibir os aniversários da data de hoje .
Por exemplo, se hoje for 4/7 (7 de abril):

7/14 Valerian
11/31 Carmen
1/23 Horace
3/1 Taraneh

Como fazer isso em um script bash?

Eu descobri como dividir um arquivo de texto baseado em um padrão (eu poderia então concatenar os splits na ordem inversa) mas aqui o truque é que a data de hoje pode estar ausente ou pode estar o aniversário de várias pessoas.

Observação: todas as datas são válidas.

    
por Nicolas Raoul 07.04.2017 / 08:47

2 respostas

8

Talvez algo como:

date +'%m/%d 0000' |
  sort -nt/ -k1 -k2 - birthdays.txt |
  awk '$2 == "0000" {past_today = 1; next}
       past_today {print; next}
       {next_year = next_year $0 RS}
       END {printf "%s", next_year}'

Ou seja, insira uma linha 04/07 0000 ( date +%-m/%-d produziria 4/7 com algumas implementações date , mas não é portátil e 04/07 funciona tão bem) antes de classificar por data e, em seguida, ter awk move as linhas que estão antes daquela para o final.

sort ... - birthdays.txt

classifica seu stdin (representado por - , aqui um pipe alimentado por date ) e o conteúdo de birthdays.txt .

Definimos o separador de chaves como / com -t/ , -k1 especifica uma chave de classificação do início ao fim da linha (em essência, -k1 especifica a linha completa como uma chave de classificação), e -k2 uma chave de classificação que começa no primeiro caractere após o primeiro / até o final da linha, mas com -n , esses são interpretados como números, portanto, apenas a sequência inicial de dígitos é importante.

(o acima funcionaria com qualquer shell parecido com o Bourne (incluindo bash ), não é necessário instalar bash apenas para isso).

    
por 07.04.2017 / 08:58
2

Primeira alteração "/" no espaço e ordenação

sed 's|/| |' data | sort -k1,1n -k2,2n >out.tmp

Em seguida, imprima as próximas datas antes e depois da anterior

awk -v m=4 -v d=7 '$1 > m || $1 == m && $2 >= d' out.tmp
awk -v m=4 -v d=7 '$1 < m || $1 == m && $2 <  d' out.tmp
    
por 07.04.2017 / 08:54