更新:自动判断文件首行是否有释伴行
Linux环境编辑文件后自动添加修改日期,
如果原文件没有File、Ctime、Mtime及Version,则自动在第一行添加。
如果原文有File、Ctime、Mtime及Version,则修改原文件对应内容的信息。
Centos,RockyLinux,Kylin通用


注:
1、空文件不处理
2、大版本号手动修改,小版本自动迭代
3、按文件类型自动调整注释符
4、可自定议哪些类型的文件触发此脚本
5、调整仅在vim中生效,所以脚本中会定义alias vi='vim'
bash
#!/bin/bash
#==============================================================
# Ctime : root 2026-05-29 09:15:43
# Mtime : root 2026-06-04 10:11:09
# Desc : config VIMRC
# Version : v3.5
#==============================================================
#备份原文件
DT=$(date +"%Y%m%d_%H%M%S")
cp /etc/bashrc /etc/bashrc_${DT}
cp /etc/vimrc /etc/vimrc_${DT}
# 检查 /etc/bashrc 是否包含 alias vi
if ! grep -q "alias vi=" /etc/bashrc; then
echo "alias vi='vim'" >> /etc/bashrc
fi
if ! grep -q "自动更新 Mtime" /etc/bashrc; then
cat >> /etc/vimrc <<'EOF'
" 自动更新 Filename + CreateTime + ModifyTime + Version(智能Shebang判断)
function! UpdateLastModified()
" 空文件不处理
if line('$') == 1 && getline(1) == ''
return
endif
" 时间与用户名
let l:current_time = strftime("%Y-%m-%d %H:%M:%S")
let l:username = exists('v:username') ? v:username : $USER
if l:username == ''
let l:username = 'unknown'
endif
let l:time_str = l:username . ' ' . l:current_time
" 获取当前文件名称(不含路径)
let l:filename = expand("%:t")
" 查找状态
let l:found_filename = 0
let l:found_create = 0
let l:found_modify = 0
let l:found_version = 0
" ==============================
" 一次遍历,并行查找所有标记
" ==============================
for l:lnum in range(line('$'), 1, -1)
let l:line = getline(l:lnum)
" 查找 Filename(只查找,不更新)
if l:found_filename == 0 && l:line =~? '^\s*\(\#\|//\|\"\)\?\s*Filename\s*:'
let l:found_filename = 1
endif
" 查找 CreateTime(只查找,不更新)
if l:found_create == 0 && l:line =~? '^\s*\(\#\|//\|\"\)\?\s*CreateTime\s*:'
let l:found_create = 1
endif
" 查找 ModifyTime(每次保存更新)
if l:found_modify == 0 && l:line =~? '^\s*\(\#\|//\|\"\)\?\s*ModifyTime\s*:'
call setline(l:lnum, substitute(l:line, 'ModifyTime\s*:\s*.*', 'ModifyTime : ' . l:time_str, ''))
let l:found_modify = 1
endif
" 查找 Version(大版本手动,小版本自动+1)
if l:found_version == 0 && l:line =~? '^\s*\(\#\|//\|\"\)\?\s*Version\s*:'
let l:major = substitute(l:line, '.*v\?\(\d\+\)\.\(\d\+\).*', '\1', '')
let l:minor = substitute(l:line, '.*v\?\(\d\+\)\.\(\d\+\).*', '\2', '')
let l:minor = l:minor + 1
let l:new_ver_str = 'v' . l:major . '.' . l:minor
call setline(l:lnum, substitute(l:line, 'Version\s*:\s*.*', 'Version : ' . l:new_ver_str, ''))
let l:found_version = 1
endif
" 都找到就提前退出
if l:found_filename && l:found_create && l:found_modify && l:found_version
break
endif
endfor
" ==============================
" 智能判断:是否有 #! shebang 行
" ==============================
let l:first_line = getline(1)
if l:first_line =~# '^#!' " 第一行是解释器声明
let l:insert_pos = 1 " 从第2行插入
else
let l:insert_pos = 0 " 从第1行插入
endif
" 注释符号
let l:ft = &filetype
if l:ft =~ '\(py\|sh\|yml\|yaml\|md\|txt\|conf\|ini\|cfg\|pl\|rb\|lua\|awk\|exp\)'
let l:cmt = '#'
elseif l:ft =~ '\(c\|cpp\|java\|js\|go\|php\|css\)'
let l:cmt = '//'
else
let l:cmt = '#'
endif
" ==============================
" 按顺序插入
" ==============================
if !l:found_filename
call append(l:insert_pos, l:cmt . ' Filename : ' . l:filename)
endif
if !l:found_create
call append(l:insert_pos+1, l:cmt . ' CreateTime : ' . l:time_str)
endif
if !l:found_modify
call append(l:insert_pos+2, l:cmt . ' ModifyTime : ' . l:time_str)
endif
if !l:found_version
call append(l:insert_pos+3, l:cmt . ' Version : v1.0')
endif
endfunction
augroup AutoTimeStamp
autocmd!
autocmd BufWritePre *.md,*.txt,*.py,*.sh,*.c,*.cpp,*.java,*.yml,*.yaml,*.conf,*.ini,*.cfg,*.pl,*.rb,*.lua,*.awk,*.exp call UpdateLastModified()
augroup END
EOF
fi