Como apenas as linhas de saída com menos de 3 meses?

4
cat a.txt
1387111124 ./asfjlasdf.txt
1348681215 ./akdfyxcv.txt

Então eu preciso disso:

cat a.txt | SOMEMAGIC
1387111124 ./asfjlasdf.txt

A saída deve ter apenas as linhas com menos de 3 meses. Como posso conseguir isso? (a primeira coluna é sempre a data do unix, a segunda é uma string sem espaços)

    
por gasko peter 15.12.2013 / 14:36

3 respostas

6

Como alternativa, se o date não der suporte a %s , com muitas implementações awk , você poderá usar srand() para obter a hora atual do Unix:

 awk 'BEGIN{srand(); d = srand() - 3 * 30 * 24 * 60 * 60}; $1 > d' < a.txt

Ou use perl :

 perl -ne'BEGIN{$d = time - 3 * 30 * 24 * 60 * 60}print if $_ > $d' < a.txt

Note que 3 meses aqui são contados como um período fixo de 90 dias de 86400 segundos cada.

Se você quiser: não antes do mesmo dia do mês, 3 meses atrás na mesma hora do dia (se agora for 2013-12-15 21:02:01, isso seria desde 2013 -09-15 21:02:01 (91 dias e 1 hora atrás em um fuso horário da União Europeia por exemplo)) , veja @ Zelda's answer , ou:

 perl -MPOSIX -ne 'BEGIN{@t=localtime;$t[4]-=3;$d=mktime @t}
                   print if $_ > $d' < a.txt

(com a ressalva de que em 29 de maio (ano não bissexto), 30 de maio e 31, 31 de julho e 31 de dezembro, a data de 3 meses atrás será a mesma do GNU date -d '3 months ago' ).

Se em vez disso, você quer dizer este mês, o anterior, ou o anterior (se hoje é 2013-12-15, seria desde 2013-10-01 00:00:00) , isso seria:

 perl -MPOSIX -ne 'BEGIN{@t=localtime;$d=mktime 0,0,0,1,$t[4]-2,$t[5]}
                   print if $_ >= $d' < a.txt
    
por 15.12.2013 / 14:53
3

Eu usaria awk e date (desde que sua implementação de data, como o GNU date , suporte o formato %s não padrão).

$ cat a.txt
1387111124 ./asfjlasdf.txt
1348681215 ./akdfyxcv.txt
$ awk -v date="$(date +%s)" '$1>(date-60*60*24*90)' a.txt
1387111124 ./asfjlasdf.txt

Use o date +%s para obter a quantidade de segundos desde 1970. Em seguida, subtraia 90 dias e verifique se a primeira coluna é maior do que isso.

    
por 15.12.2013 / 14:46
3

Em algumas das outras respostas, supõe-se que 3 meses sejam 90 dias. Isso só é verdade para um número relativamente pequeno de dias por ano. Para obter um registro de data e hora mais preciso para 3 meses antes, você pode usar o seguinte script Python (usando apenas sua biblioteca padrão). Isso é preciso, exceto para 29 de maio (ano não bissexto), 30 de maio & 31, 31 de julho e 31 de dezembro.

#!/usr/bin/env python

import sys
from datetime import datetime

now = datetime.now()
#now = datetime(2013,5,31,12,0,0)
for x in range(4): # 0 - 3 days earlier
    try:
        if now.month < 4:
            now_min_3_months = now.replace(year=now.year-1, month=now.month+9, 
                                           day=now.day-x)
        else:
            now_min_3_months = now.replace(month=now.month-3, day=now.day-x)
        break
    except ValueError:
        pass
#print (int(now_min_3_months.timestamp()))
if sys.version_info < (3,):
    import calendar
    now_min_3_months_ts = calendar.timegm(now_min_3_months.utctimetuple())
else:
    now_min_3_months_ts = now_min_3_months.timestamp()

for line in sys.stdin:
    ts, rest = line.split(' ', 1)
    if int(ts) < now_min_3_months_ts:
        continue
    sys.stdout.write(line)

Pipe a.txt neste script para obter a saída.

Obrigado a Stéphane e Anton por apontarem erros na resposta original.

    
por 15.12.2013 / 15:34

Tags