Как только произвести строки, которые моложе, чем 3 месяца?

В ext2/ext3/ext4 файловых системах 5% дискового пространства резервируются для корня в случае диска, являющегося полным, таким образом, процессы могут работать правильно. Можно проверить это с командой:

$ sudo dumpe2fs /dev/sda1 | grep Reserved

Где/dev/sda1 является устройством файловой системы (можно проверить его с командой df).

Можно изменить это значение с командой tune2fs:

$ sudo tune2fs -r 109117 /dev/sda1
4
15.12.2013, 18:40
3 ответа

С другой стороны, если Ваш date не поддерживает %s, со многими awk реализации, можно использовать srand() получить текущее время Unix:

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

Или используйте perl:

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

Обратите внимание, что 3 месяца здесь считаются как установленный срок 90 дней 86 400 секунд каждый.

Если вместо этого Вы хотите: не перед тем же днем месяца, 3 месяца назад одновременно дня (если бы теперь 15.12.2013 21:02:01, которое было бы с тех пор 15.09.2013 21:02:01 (91 день и 1 час назад в часовом поясе Европейского союза, например)), см. ответ @Zelda, или:

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

(с протестом, что 29 мая (не високосный год), 30 и 31 мая, 31-го июля и 31-го декабря, 3 месяца назад дата совпадет с для GNU date -d '3 months ago').

Если вместо этого, Вы имеете в виду в этом месяце, предыдущее, или то перед предыдущим (если бы сегодня 15.12.2013, который был бы с тех пор 01.10.2013 0:00:00), который будет:

 perl -MPOSIX -ne 'BEGIN{@t=localtime;$d=mktime 0,0,0,1,$t[4]-2,$t[5]}
                   print if $_ >= $d' < a.txt
6
27.01.2020, 20:47
  • 1
    Почему < a.txt для awk? № 2 –  Bernhard 15.12.2013, 17:33
  • 2
    @Bernhard, awk имеет некоторые проблемы с некоторыми именами файлов (те, которые содержат = символы). Наличие оболочки открывается, файл не имеет проблемы и имеет другие преимущества. интересный –  Stéphane Chazelas 15.12.2013, 22:34
  • 3
    Как насчет памяти для гипотетического случая огромного файла? –  Bernhard 16.12.2013, 08:43
  • 4
    @Bernhard, единственная разница - то, кто открывает файл для чтения (оболочка с" <" на fd 0, awk на другом fd без" <"), не те чтения из файла (awk в обоих случаях). Могли быть проблемы памяти, если строки огромны (с некоторыми awk реализациями, которые не имеют предела там), но это независимо от того, открывают ли оболочка или awk файл. –  Stéphane Chazelas 16.12.2013, 11:46
  • 5
    я тестирую awk '{}' file и awk '{}' <file на гипотетическом огромном файле (1GB), и не видел noticable различий действительно. –  Bernhard 16.12.2013, 12:27

Я использовал бы awk и date (если Ваша реализация даты, как GNU date, поддерживает нестандартное %s формат).

$ 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

Используйте date +%s получить сумму секунд с 1970. Затем substract, который проверяют 90 дней и больше ли первый столбец, чем это.

3
27.01.2020, 20:47
  • 1
    @Stephane, Почему Вам были бы нужны кавычки вокруг подоболочки для этой определенной даты? Никакие пробелы в выводе. –  Bernhard 15.12.2013, 16:39
  • 2
    [ой] Опускающий кавычки, является split+glob оператором. Разделение сделано на символах текущего значения $IFS, не обязательно располагают с интервалами. Вопрос, который я задал бы, будет: почему Вы хотите использовать split+glob оператор здесь? –  Stéphane Chazelas 15.12.2013, 22:24

В некоторых из других ответов 3 месяца, как предполагается, 90 дней. Это только верно для относительно небольшого количества дней в год. Для получения более точной метки времени в течение 3 месяцев до настоящего времени можно использовать следующий сценарий Python (только пользующийся его стандартной библиотекой). Это точно за исключением 29 мая (не високосный год), 30 и 31 мая, 31-го июля и 31-го декабря.

#!/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)

Канал a.txt в этот сценарий для получения вывода.

Спасибо переходит к Stephane и Anton для указания на ошибки в исходном ответе.

3
27.01.2020, 20:47
  • 1
    Поскольку Stephane указывает, что это не работает, Вы лучше пользуетесь нестандартной dateutil библиотекой для этого. И даже затем можно дебатировать о том, что составляет 3 месяца, до 31-го мая что-то, о чем можно дебатировать. (dateutil вычисляет, что, чтобы быть 28-го февраля) –  Anthon 15.12.2013, 16:56

Теги

Похожие вопросы