2011-08-18 182 views
79

bash history命令很酷。我明白为什么它显示行号,但有没有办法可以调用历史命令并抑制行号?没有行号的Bash历史记录

的这里点是使用history命令,所以请不要回复cat ~/.bash_history

电流输出:

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

Historical graphic source.

所需的输出:

man history 
ls 
ll 
clear 
cd ~ 
history

Historical graphic source.

感谢大家为您的出色解决方案。保罗的是最简单的,将为我工作,因为我的bash的历史大小设置为2000.

我也想分享一个很酷的文章,我今天早上发现。它有我现在使用的,喜欢养重复条目出bash的历史,并确保多的bash会话不会覆盖历史文件一对夫妇不错的选择:http://blog.macromates.com/2008/working-with-history-in-bash/

回答

132

试试这个:

$ history | cut -c 8- 
+0

我们能否管从'history'命令的输出,而不是读的文件? – cwd

+0

似乎工作!你能解释它在做什么吗?如果数字是1 - 10,000,它会起作用吗? – cwd

+0

这非常粗糙 - 你可以用sed或awk做得更好。这里的“剪切”只是删除每行的前7个字符。 –

3

history命令没有压缩行号的选项。你必须为每个人都在暗示多个命令组合:

例子:

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

如果你要通过'sed'运行它,那么最初的剪切是多余的 - 只需将它添加到表达式中即可。 – moopet

11

awk可以帮助:如果你有很长hsitory

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

This answer可能会失败。

HTH

+0

哈哈,谢谢 - substr'非常简单,我一直在使用'history | awk'{for(i = 2; i <= NF; i ++)printf(“%s”,$ i); print(“\ r”)}'' – geedoubleya

5

或者,你可以使用SED:

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

使用别名,你可以把这个作为你的标准(把它贴在你的.bash_profile):

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

基本正则表达式中的'\ +'不符合POSIX标准。如果您的'sed'不支持非标准的'\ +'扩展名,请使用'\ {1,\}'。 –

2

$ hh -n

你可能想尝试https://github.com/dvorka/hstr其中allo ws针对Bash历史的“提示框样式”过滤,其中(可选的)基于度量的排序即它是在向前和向后两个方向上更有效和更快:

enter image description here

它可以很容易地结合到CTRL-R和/或Ctrl-S键

0

虽然切断与-c选项适用于大多数实际目的,我认为将管道历史记录为awk将是更好的解决方案。例如:

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

OR

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

这两种解决方案的做同样的事情。历史的输出被输入到awk中。 Awk然后空出第一列,这对应于历史命令输出中的数字。这里awk更方便,因为您不必关心输出数字部分中的字符数。

print $0相当于print,因为默认设置是打印出现在行上的所有内容。键入print $0更明确,但您选择哪一个取决于您。如果您使用awk打印文件(cat将更快地输入而不是awk,但这是为了说明一个要点),那么使用与0123k一样的print $0和简单的print的行为更为明显。

[实施例]使用awk来显示文件的与内容$ 0

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

[实施例]使用AWK而不显示文件的内容明确的$ 0

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

[EX]当历史记录线跨越多行时使用awk

$ 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

我正在通过此线程并找到soluti ons是好的。在尝试使用awk解决方案时,发现历史上如果存在多行命令或空格等,他们可能会面临打印OP实际要求的挑战。让我举一个例子,我这​​样做了一个命令。

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

所以在历史上它将会在1序列号来,但如果这是在解决方案/ s的忽视可能是一个问题。所以下面的例子可以避免特别是多行命令被运行的情况。

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' 

的溶液的非一个衬里形式太如下:

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 
       ' 

的上面的代码说明作为太如下(一个不应该运行以下,因为它仅用于解释的目的):

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. 

虽然这个命令也可能有一些挑战,尽我所能,保持完美无缺,反馈或建议。

5

我很清楚,这个问题是bash和许多人宁愿不转的zsh(线索downvotes ...)

不过,如果你愿意切换到的zsh随后的zsh支持这一本身(以及其他选项历史格式化)

zsh> fc -ln 0 

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

+4

其实'fc'也是一个'bash'内建的。唯一的区别是第一行是'1',所以它会是'fc -ln 1' – wisbucky

+0

//有一个upvote的事实,我甚至不知道有什么替代Bash的时间最长,直到有人在这种情况下提出了他们。 –

4

我来晚了就这一个,但更短的方法是添加以下在~/.bashrc~/.profile文件:

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

从庆典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. 

使用这个功能,智能黑客在于使变量 “打印” 回车(\r),并明确该行(ANSI代码K)而不是实际的时间戳。

+0

稍微简单一点,使用更加难懂的语法:'HISTTIMEFORMAT = $'\ r \ e [K'' – wjandrea

+0

和一行选项:'HISTTIMEFORMAT = $'\ r \ e [K'history' – wjandrea

1

可以使用命令cut来解决它:

剪下从标准输入或文件的字段。

  • 剪出标准输入的每一行的第一个十六个字符: cut -c 1-16

  • 切出所给文件的每一行的第一个十六个字符: cut -c 1-16 file

  • 切出一切从第3个字符到每行的结尾: cut -c3-

  • 切出每一行的第五字段,使用冒号作为字段分隔符(缺省定界符是选项卡): cut -d':' -f5

  • 切出每一行的第二和第10字段,使用分号作为分隔符: cut -d';' -f2,10

  • 通过每一行的7切出的字段3,使用空间作为分隔符: cut -d' ' -f3-7

+0

//,你请举个例子和输出? –