После строки
my @titlewords = split /\s+/, $title; #/ get words
добавьте код для удаления слов из массива:
my @new;
foreach my $t (@titlewords){
push(@new, $t) if $t !~ /^(and|if|the)$/i;
}
@titlewords = @new;
Предположим, что сценарий, генерирующий выходные данные, называется generate
. Затем, чтобы отобразить количество секунд, необходимое для создания каждой строки:
$ generate | ( t0=$(date +%s); while read -r line; do t1=$(date +%s); echo " $((t1-t0)) $line"; t0=$t1; done )
2 foo
0 foo
5 foo
3 foo
Одни и те же команды, разбросанные по нескольким строкам, выглядят так:
generate | ( t0=$(date +%s)
while read -r line
do
t1=$(date +%s)
echo " $((t1-t0)) $line"
t0=$t1
done
)
В качестве альтернативы, для удобства, мы можем определить функцию оболочки, содержащую этот код:
timer() { t0=$(date +%s); while read -r line; do t1=$(date +%s); echo " $((t1-t0)) $line"; t0=$t1; done; }
Мы можем использовать эту функцию следующим образом:
$ generate | timer
0 foo
2 foo
4 foo
3 foo
t0=$(date +%s)
Это фиксирует текущее время в начале сценария в секундах -с эпохи -.
while read -r line; do
Это запускает цикл, который читает со стандартного ввода
t1=$(date +%s)
Это фиксирует время в секундах -с -эпохи, в которую была захвачена текущая строка.
echo " $((t1-t0)) $line"
Выводит время в секундах, которое потребовалось для текущей строки.
t0=$t1
Это обновляет t0
для следующей строки.
done
Это сигнализирует об окончании цикла while
.
Вы можете использоватьtime
(примечание :отдельный двоичный файл, а не оболочку, встроенную -в ), и комбинировать ее с циклом while. Чтобы получить время выполнения для каждой команды:
while read -r line; do
/usr/bin/time -f "%e %C" $line 2>&1
done
Пример вывода:
0.1 sleep 0.1
0.2 sleep 0.2
1.0 sleep 1
Если вы хотите получить общее время выполнения с самого начала, вам необходимо просуммировать время выполнения для каждого шага. Точность для формата %e
составляет 1/100 секунды, поэтому вы не можете использовать целочисленную арифметику оболочки напрямую (в зависимости от используемой вами оболочки ).
total=0.0
while read -r line; do
t=$(/usr/bin/time -f "%e" $line 2>&1)
total=$(awk "BEGIN{print $total+$t}")
echo "$total $line"
done
Пример вывода:
0.1 sleep 0.1
0.3 sleep 0.2
1.3 sleep 1
trickle () {
awk 'BEGIN { t = systime(); OFS="\t" }
{ print systime() - t, $0 }
{ t = systime() }'
}
Эта небольшая функция оболочки просто оборачивает awk
скрипт (, совместимый как с GNU awk
, так и mawk -Wi
, но не с BSD awk
из-за его отсутствияsystime()
). Он будет выводить каждую строку ввода с префиксом количества полных секунд с момента последней строки вывода. Первая строка будет иметь префикс нуля.
Тестирование:
$ { echo hello; sleep 2; echo world } | trickle
0 hello
2 world
Сценарий awk
, очевидно, может быть запущен и отдельно -:
$ some_command | awk 'BEGIN{OFS="\t";t=systime()}{print systime()-t,$0;t=systime()}
.
$ { echo hello; sleep 2; echo world; } | awk 'BEGIN{OFS="\t";t=systime()}{print systime()-t,$0;t=systime()}'
0 hello
2 world
Что ж, moreutilsts
кажется идеальным инструментом для этого:
$ seq 5 | pv -qL 1 | ts -s %s
2 1
4 2
6 3
8 4
10 5
Или с большей точностью:
$ seq 5 | pv -qL 1 | ts -s %.s
1.949228 1
3.933483 2
5.917923 3
7.902231 4
9.886618 5
Or с zsh
илиksh93
($SECONDS
по умолчанию является целым числом, но вы можете сделать его плавающим с помощью typeset -F
; pdksh
и bash
также имеют $SECONDS
,но только целые):
$ typeset -F SECONDS=0; seq 5 | pv -qL 1 | while IFS= read -r line; do
printf '%.3f %s\n' "$SECONDS" "$line"; done
1.987 1
3.972 2
5.956 3
7.941 4
9.925 5
$ seq 5 | pv -qL 1 | ts -i %.s
1.947814 1
1.984442 2
1.984456 3
1.984151 4
1.984195 5
zsh
/ksh93
:
$ seq 5 | pv -qL 1 | while SECONDS=0; IFS= read -r line; do
printf '%.6f %s\n' "$SECONDS" "$line"; done
1.985298 1
1.984322 2
1.984212 3
1.984240 4
1.984441 5
Сначала создайте простую функцию, использующую встроенную функцию bash SECONDS
. Обратите внимание, что мы инициализируем его нулем при каждом вызове.
_time() { SECONDS=0; out="$($@)"; echo "[${SECONDS}] ${out:-no output}"; }
Затем используйте эту функцию _time
для запуска вашей команды (s )из списка команд, может быть их файл или что-то еще.
while read cmd; do _time $cmd; done < <(echo -e "sleep 5\nsleep 2\nsleep 1")
Здесь у sleep нет вывода, но ваши команды, скорее всего, будут. Это просто для того, чтобы показать использование СЕКУНД в отношении этой проблемы. В этом примере будет выводиться вывод по умолчаниюno output
:
[5] no output
[2] no output
[1] no output