Вы не можете напрямую | 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
решение для строки прогресса Дан файл 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(...)
.
Если ваши данные однородны, напр.
$ 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
(по умолчанию, оно анализируется как целое число ).
Можно напечатать день года с%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