2011-08-18 26 views
79

Lệnh bash history rất tuyệt. Tôi hiểu lý do tại sao nó cho thấy số dòng, nhưng có cách nào tôi có thể gọi lệnh lịch sử và ngăn chặn các số dòng?Lịch sử Bash không có số dòng

Vấn đề ở đây là sử dụng lệnh lịch sử, vì vậy xin vui lòng đừng trả lời cat ~/.bash_history

Output hiện tại:

529 man history 
    530 ls 
    531 ll 
    532 clear 
    533 cd ~ 
    534 history

Historical graphic source.

mong muốn Output:

man history 
ls 
ll 
clear 
cd ~ 
history

Historical graphic source.

Cảm ơn mọi người vì những giải pháp tuyệt vời của bạn. Paul là đơn giản nhất và sẽ làm việc cho tôi vì kích thước lịch sử bash của tôi được đặt vào năm 2000.

Tôi cũng muốn chia sẻ một bài viết hay mà tôi đã tìm thấy sáng nay. Nó có một vài lựa chọn tốt mà bây giờ tôi đang sử dụng, như giữ mục trùng lặp ra khỏi lịch sử bash và đảm bảo nhiều phiên bash không ghi đè lên các tập tin lịch sử: http://blog.macromates.com/2008/working-with-history-in-bash/

Trả lời

132

Hãy thử điều này:

$ history | cut -c 8- 
+0

Can chúng ống trong đầu ra từ 'lệnh history' thay vì đọc các tập tin? – cwd

+0

Dường như làm việc! Bạn có thể giải thích những gì nó đang làm? Nó sẽ hoạt động nếu các con số là 1 - 10.000? – cwd

+0

Nó khá thô - bạn có thể làm tốt hơn với sed hoặc awk. 'cut' ở đây chỉ là tước bỏ 7 ký tự đầu tiên của mỗi dòng. –

3

Lệnh history không có tùy chọn để chặn số dòng. Bạn sẽ phải kết hợp nhiều lệnh như tất cả mọi người được gợi ý:

Ví dụ:

history | cut -d' ' -f4- | sed 's/^ \(.*$\)/\1/g' 
+0

Nếu bạn định chạy nó thông qua 'sed', thì việc cắt đầu tiên là thừa - chỉ cần thêm nó vào biểu thức thay thế. – moopet

11

awk có thể giúp:

history|awk '{$1="";print substr($0,2)}' 

This answer có thể thất bại nếu bạn có một hsitory dài.

HTH

+0

Ha Ha, cảm ơn - 'substr' đơn giản hơn rất nhiều, tôi đã sử dụng' history | awk '{cho (i = 2; i <= NF; i ++) printf ("% s", $ i); in ("\ r")}' 'cho tôi !! – geedoubleya

5

Ngoài ra, bạn có thể sử dụng sed:

history | sed 's/^[ ]*[0-9]\+[ ]*//' 

Sử dụng bí danh, bạn có thể thiết lập này như là tiêu chuẩn của bạn (dính nó trong bash_profile của bạn):

alias history="history | sed 's/^[ ]*[0-9]\+[ ]*//'" 
+1

'\ +' trong cụm từ thông dụng cơ bản không phải là tuân thủ POSIX. Sử dụng '\ {1, \}' nếu 'sed' của bạn không hỗ trợ phần mở rộng' \ + 'không chuẩn. –

2

$ hh -n

Bạn có thể muốn thử https://github.com/dvorka/hstr mà allo ws cho "đề xuất kiểu hộp" lọc lịch sử Bash với (tùy chọn) số liệu dựa trên thứ tự tức lànó là hiệu quả hơn và nhanh hơn trong cả hai hướng về phía trước và lạc hậu:

enter image description here

Nó có thể dễ dàng liên kết với Ctrl-r và/hoặc Ctrl-s

0

Mặc dù cắt với -c tùy chọn làm việc cho hầu hết các mục đích thực tế, tôi nghĩ rằng lịch sử đường ống để awk sẽ là một giải pháp tốt hơn. Ví dụ:

history | awk '{ $1=""; print }' 

HOẶC

history | awk '{ $1=""; print $0 }' 

Cả hai giải pháp làm điều tương tự. Đầu ra của lịch sử đang được cho ăn để awk. Awk sau đó điền vào cột đầu tiên, tương ứng với các số trong đầu ra của lệnh lịch sử. Ở đây awk là thuận tiện hơn bởi vì bạn không phải quan tâm chính mình với số lượng ký tự trong phần số của đầu ra.

print $0 tương đương với print, vì mặc định là in mọi thứ xuất hiện trên dòng. Nhập print $0 rõ ràng hơn nhưng bạn chọn tùy chọn nào. Các hành vi của print $0 và chỉ đơn giản là print khi được sử dụng với awk là hiển nhiên hơn nếu bạn sử dụng awk để in một tập tin (cat sẽ nhanh hơn để gõ thay vì awk, nhưng điều này là để minh họa một điểm).

[Ex] Sử dụng awk để hiển thị nội dung của một tập tin với $ 0

$ awk '{print $0}' /tmp/hello-world.txt 
Hello World! 

[Ex] Sử dụng awk để hiển thị nội dung của một tập tin mà không rõ ràng $ 0

$ awk '{print}' /tmp/hello-world.txt 
Hello World! 

[Ex] Sử dụng awk khi dòng lịch sử kéo dài nhiều dòng

$ history 
    11 clear 
    12 echo "In word processing and desktop publishing, a hard return or paragraph break indicates a new paragraph, to be distinguished from the soft return at the end of a line internal to a paragraph. This distinction allows word wrap to automatically re-flow text as it is edited, without losing paragraph breaks. The software may apply vertical whitespace or indenting at paragraph breaks, depending on the selected style." 

$ history | awk ' $1=""; {print}' 
clear 
echo "In word processing and desktop publishing, a hard return or paragraph break indicates a new paragraph, to be distinguished from the soft return at the end of a line internal to a paragraph. This distinction allows word wrap to automatically re-flow text as it is edited, without losing paragraph breaks. The software may apply vertical whitespace or indenting at paragraph breaks, depending on the selected style." 
-1

Tôi đã trải qua chuỗi này và tìm thấy soluti là tốt. Trong khi thử một giải pháp awk thấy rằng trong lịch sử nếu có nhiều dòng lệnh có hoặc không gian vv họ có thể có những thách thức để in những gì yêu cầu thực tế của OP là. Hãy để tôi đưa ra một ví dụ ở đây, tôi chạy một lệnh như thế này.

awk ' 
match ($0, /<property class="java.lang.String" name="WorkJobNumber" value="[0-9]*"\/>/) {sub (substr ($0, RSTART+63, RLENGTH-66), _) 
                         } 
1123 
' Input_file 

Vì vậy, trong lịch sử nó sẽ đến dưới 1 số thứ tự nhưng có thể là vấn đề nếu điều này bị bỏ qua trong giải pháp. Vì vậy, sau đây có thể tránh một tình huống mà các lệnh đa dòng đặc biệt đã được chạy.

history | awk '{Q=$1;sub(/^[[:space:]]+/,"",Q);if(LAST+1==Q && LAST && Q ~ /^[0-9]+/){;$1="";print;} else {print;};if(Q ~ /^[0-9]+/ && Q+0 == LAST+1 && $0 !~ /^$/){LAST=Q+0};next} (Q ~ /^[0-9]+/ && $0 !~ /^$/){LAST=Q+0} 1' 

A-one phi hình thức lót của giải pháp quá như sau:

history | awk '{ 
     Q=$1; 
     sub(/^[[:space:]]+/,"",Q); 
     if(LAST+1==Q && LAST && Q ~ /^[0-9]+/){; 
          $1=""; 
          print; 
           } 
       else         { 
          print; 
            }; 
       if(Q ~ /^[0-9]+/ && Q+0 == LAST+1 && $0 !~ /^$/){ 
           LAST=Q+0 
             }; 
       next 
       } 
       (Q ~ /^[0-9]+/ && $0 !~ /^$/){ 
          LAST=Q+0 
              } 
       1 
       ' 

Giải thích về mã trên như sau quá (người ta không nên chạy sau khi nó chỉ dành cho mục đích giải thích):

history |           #### Running history command here and using pipe to use this command's standard output to standard input for next awk command. 
awk '            #### Starting awk command from here. 
{Q=$1            #### Starting a variable named Q, whose value is $1 of current line. 
sub(/^[[:space:]]+/,"",Q)       #### subsitute initial space of variable Q(which has $1 of current line too) to NULL now. 
if(LAST+1==Q && LAST && Q ~ /^[0-9]+/)    #### mentioning here a if condition which is checking following conditions. 
               i- check if variable named LAST's value +1 is equal to variable Q's value(where LAST variable is the variable which has previous line's number. 
               ii- check LAST's value should NOT be NULL. 
               iii- check variable Q's value should be always starting from digits(As running multi-lie commands eg--> awk you could have commands there so making sure our LAST variable doesn't have any junk in it). 
{;$1="";print;}         #### making $1's value NULL so that history number will not print and then printing the current line. 
else            #### Mentioning else, in case above if condition is NOT TRUE then following statements should execute. 
{;print}           #### simply print the current line. 
;if(Q ~ /^[0-9]+/ && Q+0 == LAST+1 && $0 !~ /^$/) #### checking following conditions here. 
               i- check if variable Q's value always starts from digits to make sure no junk will come apart from history numbers in variable here. 
               ii- check Q+0 == LAST+1, here Q+0 I am mentioning because in my history it was showing 772*(in a row) so Q+0 will make sure only numbers are being captured here. then comparing it with LAST+1 value, if both are equal here. 
               iii- Making sure each line starts NOT from a space(in multi-line commands you may see spaces). 
{LAST=Q+0};next}         #### Assigning variable LAST's value to Q's value(by doing Q+0 making sure like only digits should be captured here). Mentioning next here which is awk's in-built keyword and will skip all next statements then. 
(Q ~ /^[0-9]+/ && $0 !~ /^$/)      #### This condition will be executed when previous are not true, checking Q's value should be starting from digits only to get the history's sequence number only and checking a line shouldn't start from space etc. 
{LAST=Q+0}           #### Assigning variable LAST's value to value of Q+0 which will make sure only digits should come. 
1'             #### So awk works on pattern{action} method, so by mentioning 1 I am making a pattern/condition true and then not mentioning any action here so by default print action will happen and it will print the current line, it will happen only in those cases when a history doesn't have any sequence number in it. 

Mặc dù lệnh này cũng có thể có một số thách thức, đã cố gắng hết sức để giữ cho nó hoàn hảo, mở để phản hồi hoặc đề xuất.

5

Tôi khá biết rằng câu hỏi này là dành cho bash và nhiều người muốn không chuyển sang zsh (cue downvotes ...)

Tuy nhiên, nếu bạn đã sẵn sàng để chuyển sang zsh sau đó zsh hỗ trợ này nguyên bản (cũng như các lựa chọn khác để định dạng lịch sử)

zsh> fc -ln 0 

(Xem https://serverfault.com/questions/114988/removing-history-or-line-numbers-from-zsh-history-file)

+4

Thực ra 'fc' cũng là một nội trang' bash'. Sự khác biệt duy nhất là dòng đầu tiên là '1', do đó, nó sẽ là' fc -ln 1' – wisbucky

+0

//, có một upvote cho thực tế là tôi thậm chí không biết có những lựa chọn thay thế cho Bash trong thời gian dài nhất cho đến khi ai đó đưa họ lên trong một bối cảnh như thế này. –

4

tôi đến trễ một ngày này, nhưng phương pháp ngắn hơn sẽ có thêm những điều sau đây trong ~/.bashrc hay ~/.profile bạn file:

HISTTIMEFORMAT="$(echo -e '\r\e[K')"

Từ bash manpage:

  HISTTIMEFORMAT 
       If this 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 history entry displayed by the history builtin. If 
       this variable is set, time stamps are written to the history 
       file so they may be preserved across shell sessions. This uses 
       the history comment character to distinguish timestamps from 
       other history lines. 

Sử dụng khả năng này, một hack thông minh bao gồm trong việc đưa ra các biến "in" một trở về vận chuyển (\r) và rõ ràng dòng (mã ANSI K) thay vì dấu thời gian thực.

+0

Đơn giản hơn một chút, sử dụng cú pháp tối nghĩa hơn: 'HISTTIMEFORMAT = $ '\ r \ e [K'' – wjandrea

+0

Và tùy chọn một dòng:' HISTTIMEFORMAT = $' \ r \ e [K 'history' – wjandrea

1

Bạn có thể sử dụng lệnh cut để giải quyết nó:

Cắt ra các lĩnh vực từ STDIN hoặc các tập tin.

  • Cắt ra mười sáu ký tự đầu tiên của mỗi dòng STDIN: cut -c 1-16

  • Cắt ra mười sáu ký tự đầu tiên của mỗi dòng của các tập tin đưa ra: cut -c 1-16 file

  • Cắt ra tất cả mọi thứ từ ký tự thứ 3 đến cuối mỗi dòng: cut -c3-

  • Cắt lĩnh vực thứ năm của mỗi dòng, sử dụng dấu hai chấm như một dấu phân cách trường (delimiter mặc định là tab): cut -d':' -f5

  • Cắt ra các lĩnh vực thứ 2 và thứ 10 của mỗi dòng, sử dụng một dấu chấm phẩy là một dấu phân cách: cut -d';' -f2,10

  • Cắt ra các lĩnh vực từ 3 đến 7 của mỗi dòng, sử dụng một không gian như một delimiter: cut -d' ' -f3-7

+0

//, Sẽ bạn vui lòng hiển thị một ví dụ và đầu ra? –

Các vấn đề liên quan