2013-12-12 4 views
4

Я хотел бы сделать что-то вродеистория Bash между двумя точками во времени

history 2960-2966 

с ожиданием этого вида продукции:

2960 2013-12-09 20:59:35 bundle update 
2961 2013-12-09 21:00:08 git st 
2962 2013-12-09 21:00:12 git add . 
2963 2013-12-09 21:01:19 git st 
2964 2013-12-09 21:01:43 git log 
2965 2013-12-09 21:02:45 git st 
2966 2013-12-09 21:02:57 git reset HEAD Gemfile.lock 

Возможно ли это в Баш оболочки?

ОБНОВЛЕНИЕ: Мой вопрос состоит в том, чтобы увидеть эти семь строк истории, а не даты, как таковые; просто случается, что у меня есть директива HISTTIMEFORMAT в моем .bash_profile, чтобы указать дату и время. Если бы я, чтобы удалить его, то я хотел бы history 2960-2966 или что-то, чтобы произвести этот вывод:

2960 bundle update 
2961 git st 
2962 git add . 
2963 git st 
2964 git log 
2965 git st 
2966 git reset HEAD Gemfile.lock 

Я хочу нужные строки истории, которые будут отображаться, предпочтительно с какими-либо настройками я указал в .bash_profile ,

Зачем мне это нужно? Очень простой пример использования: я делаю что-то вроде history | grep 'bundle update', получаю приличный результат, а затем хочу увидеть некоторую историю с этой точки плюс несколько строк дальше или, возможно, брекетинг истории.

+0

Вы должны это сделать, используя [Git Tags] (http://git-scm.com/docs/git-tag). См. Нижнюю часть страницы. – Brian

+0

Как отмечает @Tharanga Abeyseela в своем ответе, у меня есть отображение даты в моей истории из-за директивы 'HISTTIMEFORMAT = '% F% T'' в моем .bash_profile. – Purplejacket

+0

Эй, @Brian, этот вопрос не о git вообще, это только что оказались линиями в тот момент моей истории. – Purplejacket

ответ

3

Вы можете использовать sed. Скажи:

history | sed -n '2960,2966p' 

на номера строк 2960 до 2966 от выхода history команды.

Цитирование help history:

If the $HISTTIMEFORMAT variable is set and not null, its value is used 
as a format string for strftime(3) to print the time stamp associated 
with each displayed history entry. No time stamps are printed otherwise. 

Вы можете установить формат, чтобы получить временную метку в нужном формате, говоря:

export HISTTIMEFORMAT="%F %T " 

Поскольку файл history записывается по умолчанию только после закрытия сессии, вам следует сказать:

history -w 

для заказа для обновления файла истории в текущем сеансе.

+0

Это выражение 'sed' не работает для меня. На выходе нет вывода, тогда как функция histrange, определенная в моем ответе, работает (на Ubuntu 12.04) http://stackoverflow.com/questions/20554927/bash-history-between-two-points-in-time/ 20604325 # 20604325. Можете ли вы объяснить, как это выражение 'sed' должно работать? –

+0

@DigitalTrauma это решение работало для меня на OSX 10.9.1 (Mavericks). Вы знаете, почему это не работает на Ubuntu? Мне нравится решение devnull, потому что я мог бы даже просто запомнить его, но разве это не универсально? – Purplejacket

+0

@Purplejacket - 'history' представляет круговой буфер - после заполнения буфера старые записи будут перезаписаны более новыми. Это означает, что вывод 'history' может содержать, например, список записей 834-1833 буфера истории, если буфер уже завернут (как это, по-видимому, делает 1000 на Ubuntu). Таким образом, номер строки вывода 'history' не обязательно соответствует номеру записи истории. Решение 'sed' от devnull вводится с номера строки (путем подсчета строк вывода). Мои решения привязаны к фактическим номерам записей 'history'. –

1

попробуйте выполнить следующую команду. это будет отображать диапазон от 2960 до 2966

fc -ln 2960-2966 

выполнить их, вы можете попробовать это

eval "$(fc -ln 2960 2966)" 

Надеется, что это помогает.

Tharanga Abeyseela

+0

Я попробовал эту команду 'fc' и отобразил строки истории с 2960, но не остановился на 2966. – Purplejacket

+0

Мне не нужно повторно запускать эти строки истории, просто отобразите их в хорошем формате. – Purplejacket

+1

это хорошая ссылка.http: //www.computerhope.com/unix/uhistory.htm –

1

Мы хотим отображать записи от start до end включительно.

$HISTCMD переменная, встроенная в , дает the number of the latest entry to the history buffer.
Команда history принимает параметр n, который сообщает ему, чтобы он отображал последние записи n.Таким образом, стартовый номер при отображении записей с параметром n будет:

start = $HISTCMD - n 

Перегруппировка с точки зрения n мы получим это выражение, которое можно передать history:

n = $HISTCMD - start 

Теперь мы хотим показать только записи от start до end включительно, т.е. end - start + 1 записей. Мы можем использовать head, чтобы дать только те шапки.

Обертывание это вверх в простой в использовании функции мы имеем:

 
$ function histrange { 
>  history $(($HISTCMD - $1)) | head -n$(($2 - $1 + 1)) 
> } 
$ histrange 2097 2100 
2097 2013-12-15 21:54:02 man ls 
2098 2013-12-15 21:54:06 ls 
2099 2013-12-15 21:54:10 man df 
2100 2013-12-15 21:54:15 df -k . 
$ 
1

Вот способ сделать это с :

 
$ function histrange { 
> history | grep -E -A $(($2 - $1)) "^[[:space:]]*$1[[:space:]]" 
> } 
$ histrange 2100 2105 
2100 2013-12-15 21:54:15 df -k . 
2101 2013-12-15 21:54:18 history 
2102 2013-12-15 21:54:40 histrange 2097 2100 
2103 2013-12-15 21:55:30 man grep 
2104 2013-12-15 22:35:33 man history 
2105 2013-12-15 22:38:35 export HISTTIMEFORMAT="%F %T " 
$ 

Мы уверены, что регулярное выражение привязывается до начала строки, имеет ноль или более пробелов перед стартовым номером и один пробел после стартового номера, поэтому мы точно сопоставляем начальный номер с номером записи истории и больше ничего. Мы используем опцию -A для grep для отображения линий $end - $start после матча.

0
$> export HISTTIMEFORMAT=" %F %T  " 

затем:

$> history | awk '{if (1070<=$1 && $1<=1075) {print}}' 

Это почти реакция devnull. Никогда, хотя это было раньше, но мне понравилась идея и подумал, что это будет полезно для меня тоже. Я получаю аппроксимативный ответ от встроенной справки bash.

$> help history 

...

Если переменная $ HISTTIMEFORMAT установлена ​​и не пуста, то его значение используется в качестве строки формата для STRFTIME (3), чтобы напечатать штамп времени, связанный с каждым отображается запись истории. Никакие штампы времени не печатаются иначе.

затем

$> man 3 srtftime 
1

Ь -l 2960 2966

Это работает на OS 10.6.X. Он дает именно то, что вам нужно. Надеюсь это поможет!

+0

Это потрясающе просто и хорошо. Я могу подтвердить, что работает в Linux Mint (производная Ubuntu). Вы знаете, работает ли он в других Unix? – Purplejacket

+0

Насколько я могу судить, 'fc' широко доступен: http://alasir.com/books/bsd/211-214.html – Purplejacket

+0

@Purplejacket Спасибо, да, вы правы, пока fc доступен. – JSR

1

Учитывая то, что вы говорите, под почему вы хотите этого,

history | grep -A 4 -B 3 whatyousearchfor 

должен дать вам только то, что вы хотите.

whatyousearchfor может быть либо вашим исходным термином, либо вы сначала выполняете grep без контекстных строк, а затем используйте номер строки истории как whatyousearchfor.

Смежные вопросы