Добавить день года в виде числа от 1 до 365/366 в файл

Вы не можете напрямую | grepвыводить результаты выполнения curl из-за буферизации канала. Некоторые важные идеи по этой проблеме доступны в этом предыдущем вопросе:Отключить буферизацию в канале

Что касается решения,используя stdbufиtr:

curl https://example.com -o example.html 2>&1 | stdbuf -oL tr -s '\r' '\n' | while read i; do echo -en "\r$i  "; done

С:

  • stdbuf -oL:stdout of trбудет буферизован для правильной обработки циклом while
  • tr -s '\r' '\n':заменить возврат каретки на новую строку из curlвывода
  • while read i; do echo -en "\r$i "; done:простое bashрешение для строки прогресса

0
04.11.2019, 02:17
3 ответа

Дан файл fileс содержимым

19610101   060000  0.4  G
19610101   120000  2.3  G
19610101   180000 ... .
19610102   150000 ... .
19610102   180000 ... .
19610103   060000 ... .
20150901  ...... ... .

мы можем использовать GNU awkилиmawk(оба имеют mktime()иstrftime()):

awk '
    {
        tspec = sprintf("%4d %.2d %.2d 00 00 00", substr($1,1,4), substr($1,5,2), substr($1,7,2))
        t = mktime(tspec)
        $(NF+1) = strftime("%j",t)
    } { print }' file

Это создает отметку времени Unix, t, из даты, проанализированной из первого столбца файла (полночь, используемая в качестве времени ). Затем он форматирует метку времени, используя strftime()с форматом %j, что даст нам день года в виде целого числа, заполненного нулями -(, см.man strftime). Это число вставляется как новый столбец, а затем печатается строка.

Результат:

19610101 060000 0.4 G 001
19610101 120000 2.3 G 001
19610101 180000.... 001
19610102 150000.... 002
19610102 180000.... 002
19610103 060000.... 003
20150901.......... 244

Чтобы избавиться от заполнения нулями, используйте $(NF+1) = 0 + strftime(...).

4
28.01.2020, 02:17

Если ваши данные однородны, напр.

$ cat file
Date       Time
19610101   060000
19610101   120000
19610101   060000
19610102   120000
19610102   060000
19610102   120000
20150901   060000

тогда Миллер(mlr)может быть хорошим выбором:

$ mlr --pprint --fs " " --repifs put -S '
    $Day = strftime(strptime($Date,"%Y%m%d"),"%j")
' file
Date     Time   Day
19610101 060000 001
19610101 120000 001
19610101 060000 001
19610102 120000 002
19610102 060000 002
19610102 120000 002
20150901 060000 244

Обратите внимание на использование -Sдля приведения неограниченного поля YYYYmmmddк строковому типу дляstrptime(по умолчанию, оно анализируется как целое число ).

0
28.01.2020, 02:17

Можно напечатать день года с%j(аналогично юлианскому дню ).

Это доступно в большинстве реализаций даты.

Таким образом, ваша входная строка, имеющая формат %Y%m%d %H%M%S, должна быть изменена на %Y%m%d %j %H%M%S. Это легко с датой busybox:

$ busybox date -D '%Y%m%d %H%M%S' -d '19610101 060000' +'%Y%m%d %j %H%M%S'
19610101 001 060000

Но в Busybox date нет опции -fдля прямой обработки всех строк файла. Возможные варианты: добавить оболочку awk для вызова даты busybox для каждой строки или изменить исходный файл, чтобы даты были как 1961/01/01 06:00:00, что-то, что может читать дата GNU.

$ date -d '1961/01/01     06:00:00' +'%Y%m%d %j %H%M%S'
19610101 001 060000

поэтому используйте sed для преобразования файла (удаляя пустые строки и текстовые строки, чтобы дата не захлебывалась при вводе):

$ sed -E '/^[^0-9]|^$/d;
          s#(....)(..)(..)[[:blank:]]*(..)(..)(..)#\1/\2/\3 \4:\5:\6#' \
          datefile >newdatefile

А затем обработайте его с (одним экземпляром даты ).

$ date -f newdatefile +'%Y%m%d %j %H%M%S' > outputfile
0
28.01.2020, 02:17

Теги

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