bash 将历史文件中的哈希标签时间戳转换为所需的字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10665396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
converting the hash tag timestamps in history file to desired string
提问by user1356163
when i store the output of history command via ssh in a file i get something like this
当我通过 ssh 将历史命令的输出存储在一个文件中时,我得到了这样的东西
ssh -i private_key user@ip 'export HISTFILE=~/.bash_history; export HISTTIMEFORMAT="%D-%T "; set -o history; history' > myfile.txt
OUTPUT
输出
#1337431451
command
as far as ive learnt this hash string represents a timestamp. how do i change this to a string of my desired format
据我所知,这个哈希字符串代表一个时间戳。我如何将其更改为所需格式的字符串
P.S- using history in ssh is not outputting with timestamps. Tried almost everything. So i guess the next best thing to do would be to convert these # timestamps to a readable date time format myself. How do i go about it?
PS- 在 ssh 中使用历史记录不输出时间戳。几乎所有的东西都试过了。所以我想下一个最好的办法是自己将这些 # 时间戳转换为可读的日期时间格式。我该怎么做?
采纳答案by nosid
Interesting question: I have tried it but found no simple and clean solution to access the history in a non-interactive shell. However, the format of the history file is simple, and you can write a script to parse it. The following python script might be interesting. Invoke it with ssh -i private_key user@ip 'path/to/script.py .bash_history':
有趣的问题:我已经尝试过了,但没有找到在非交互式 shell 中访问历史记录的简单而干净的解决方案。但是,历史文件的格式很简单,你可以写一个脚本来解析它。以下 python 脚本可能很有趣。调用它ssh -i private_key user@ip 'path/to/script.py .bash_history':
#! /usr/bin/env python3
import re
import sys
import time
if __name__ == '__main__':
pattern = re.compile(br'^#(\d+)$')
out = sys.stdout.buffer
for pathname in sys.argv[1:]:
with open(pathname, 'rb') as f:
for line in f:
timestamp = 0
while line.startswith(b'#'):
match = pattern.match(line)
if match: timestamp, = map(int, match.groups())
line = next(f)
out.write(time.strftime('%F %T ', time.localtime(timestamp)).encode('ascii'))
out.write(line)
回答by tmf glzkv
you can combine rows with paste command:
您可以将行与粘贴命令组合:
paste -sd '#\n' .bash_history
and convert date with strftime in awk:
并在 awk 中使用 strftime 转换日期:
echo 1461136015 | awk '{print strftime("%d/%m/%y %T",)}'
as a result bash history with timestamp can be parsed by the next command:
因此,可以通过下一个命令解析带有时间戳的 bash 历史记录:
paste -sd '#\n' .bash_history | awk -F"#" '{d= ; ="";print NR" "strftime("%d/%m/%y %T",d)" "#1461137765
echo lala
#1461137767
echo bebe
}'
which converts:
它转换:
1 20/04/16 10:36:05 echo lala
2 20/04/16 10:36:07 echo bebe
to
到
#!/bin/bash
paste -sd '#\n' | awk -F"#" '{d= ; ="";print NR" "strftime("%d/%m/%y %T",d)" "fhistory .bash_history
}'
also you can create script like /usr/local/bin/fhistorywith content:
您也可以使用内容创建像/usr/local/bin/fhistory这样的脚本:
awk -F\# '/^#1[0-9]{9}$/ { if(cmd) printf "%5d %s %s\n",n,ts,cmd;
ts=strftime("%F %T",); cmd=""; n++ }
!/^#1[0-9]{9}$/ { if(cmd)cmd=cmd " " awk -F\# '/^#1[0-9]{9}$/ { if(cmd) printf "%s %s\n",ts,cmd;
ts=strftime("%F %T",); cmd="" }
!/^#1[0-9]{9}$/ { if(cmd)cmd=cmd "\n" gawk -F\# -v histtimeformat="$HISTTIMEFORMAT" '
/^#1[0-9]{9}$/ { i= FS NR; cmd[i]="" }
!/^#1[0-9]{9}$/ { if(cmd[i]) cmd[i]=cmd[i] "\n" ##代码##; else cmd[i]=##代码## }
END { PROCINFO["sorted_in"] = "@ind_str_asc"
for (i in cmd) { split(i,arr)
print strftime(histtimeformat,arr[1]) cmd[i]
}
}'
; else cmd=##代码## }' .bash_history
; else cmd=##代码## }' .bash_history
and quickly parse bash history file with next command:
并使用下一个命令快速解析 bash 历史文件:
##代码##回答by xebeche
Using just Awk and in a slightly more accurate way:
仅使用 awk 并以更准确的方式使用:
##代码##This parses only lines starting with something that looks like a timestamp (/^#1[0-9]{9}$/), compiles all subsequent lines up until the next timestamp, combines multi-line commands with " "(1 space) and prints the commands in a format similar to historyincluding a numbering.
这仅解析以时间戳 ( /^#1[0-9]{9}$/)开头的行,编译所有后续行直到下一个时间戳,将多行命令与" "(1 个空格)组合在一起,并以类似于history包含编号的格式打印命令。
Note that the numbering does not (necessarily) match if there are multi-line commands.
请注意,如果有多行命令,编号不会(必然)匹配。
Without the numbering and breaking up multi-line commands with a newline:
没有编号和用换行符分解多行命令:
##代码##Finally, a quick and dirty solution using GNU Awk (gawk) to also sort the list:
最后,使用 GNU Awk (gawk) 对列表进行排序的快速而肮脏的解决方案:
##代码##
