편집 후 수정 된 타임 스탬프 유지


20

특정 폴더 내에있는 파일의 경우, "mified"타임 스탬프를 전혀 건드리지 않기 위해 vim을 원합니다.

배경은 블로그에 Bloxsom 을 사용 한다는 것 입니다. 블로그 ~/bloxsom에는 모든 기사의 소스로 일반 텍스트 파일을 사용합니다 . 기사 날짜 (및 표시 순서)는 텍스트 파일의 수정 날짜를 기준으로합니다. 오타를 고칠 때마다 기사가 새로워 지는 것처럼 기사 팝업이 표시되는 것을 원하지 않습니다 . (나는 그들 중 많은 일 을한다 ... : D)

지금까지 vim은 타임 스탬프를 변경하고 원본 스탬프는 영원히 손실됩니다. 이것은 괜찮으며 시스템의 대부분의 파일에 대해 그렇게 유지하고 싶습니다. 그러나 블로그 파일에 대해서는 원하지 않습니다 touch. 필요한 경우 언제든지 파일을 사용할 수 있습니다 .

vim을이 동작으로 조정하는 방법에 대한 아이디어가 있습니까?


2
vim.wikia.com/wiki/…- 물론 펄 바인딩을 대신 사용할 수 있습니다
Ulrich Dangel

답변:


22

vim에이 기능이 있다고 생각하지 않습니다. 한 가지 대안은 사본을 수정하고 타임 스탬프를 적절하게 설정하는 것입니다. 예 :

cp -p post temp
vim temp
touch -r post temp
cp -p temp post

또는 더 나은 :

touch -r post timestamp
vim post
touch -r timestamp post

7

재미가 필요한 경우 :

file=path; mtime=$(stat -c %y "$file"); vi "$file"; touch -d "$mtime" "$file"

경로를 실제 파일 경로로 바꾸십시오


5

나는이를 위해 Perl 스크립트를 작성했다.

그것은 vim을 감싸는 래퍼 이며 내 .bashrc에서 저장 ~/bin/vim-nomtime.pl하고 사용 alias vim='~/bin/vim-nomtime.pl'합니다.

#!/usr/bin/perl
use strict;
use warnings;
use Cwd qw/ abs_path /;

my @dirs = qw( ~/blosxom /srv/relief/blosxom );

s/^~/$ENV{HOME}/ foreach @dirs;

# do we want to preserve stamp on this file?
sub fits {
    my $dir = abs_path($_[0]);
    my $fits = 0;
    foreach (@dirs) {
        my $preserved_dir = abs_path($_);
        $fits++ if $dir =~ m|^$preserved_dir|;
    }
    return $fits != 0;
}

# store original stamps
my $original_stamp;
foreach (@ARGV) {
    if ( -f $_ and fits($_) ) {
        $original_stamp->{$_} = (stat($_))[9];
    }
}

# run vim as you would
my $cmd = join ' ', 'vim', @ARGV;  
system($cmd) == 0
    or die "vim failed: $!";

# restore stamps if they have changed
foreach (keys %$original_stamp) {
    next unless -f $_;
    my $current_stamp = (stat($_))[9];
    unless ($current_stamp == $original_stamp->{$_}) {
        utime $original_stamp->{$_}, $original_stamp->{$_}, $_;
    }
}

몇 가지 좋은 기능 :

  • 여러 파일 이름을 지원합니다

  • 여러 개의 "감시 된"디렉토리 지원

  • symlinked dir 지원

  • 다른 기준으로 강화 될 수있다

대부분의 경우 순수한 vim 버전으로도 가능합니다. 내가 원하는 순수한 Vim 솔루션과 비교 하여이 솔루션의 단점은 다음과 같습니다.

  • vim이 종료 된 후에 만 스탬프를 복원 하므로, 긴 편집을하고 정기적으로 저장하면 vim을 종료 할 때까지 파일 vill이 "팝업"됩니다.

  • 명령 줄에서 여러 파일을 지원하지만 매우 순진한 방식 @ARGV으로 파일이 파일 인지 확인 합니다. 와일드 카드 (예 :) vim note-*.txt또는 기타 재미있는 항목 에서는 작동하지 않을 수 있습니다.

  • 그것은 충돌 증거가 아니며 아마도 HUP-proof조차도 아닙니다.

  • ... 래퍼입니다. (래퍼를 통해 모든 것을 해결했다면 나쁜 일이 발생하기 전에 얼마나 많은 래퍼를 갖게 될까요?)


2019 년 5 월 3 일에 방금 2017 년 11 월 11 일부터 파일을 수정했으며 수정 사항이 있으며 원래 타임 스탬프를 유지합니다. :)
jmort253

1

이 짧은 스크립트는 파일의 상위 디렉토리에 파일이있는 경우 수정 된 시간을 유지 .nomtime합니다.

#!/bin/bash

dir="${1%/*}"
[ "$dir" = "$1" ] && dir=.
dir=$( readlink -f "$dir" )

nomtime=
while [ -n "$dir" ]; do
    if [ -f "$dir/.nomtime" ]; then
        nomtime=1
        break
    fi
    dir="${dir%/*}"
done

if [ "$nomtime" = 1 ]; then
    T=`tempfile`
    touch -r "$1" $T
fi

vi "$1"

if [ "$nomtime" = 1 ]; then
    touch -r $T "$1"
    rm $T
fi

1

bash기능을 사용해보십시오 ( Shâu Shắc의 답변을 기반으로 )

vi-preserve-time () {
    for file in "$@"; do
        local mtime=$(stat -c %y "$file")
        vi "$file"
        touch -d "$mtime" "$file"
    done
}

이제 이것을 사용하여 파일을 편집하고 수정 된 시간을 보존 할 수 있습니다

vi-preserve-time file1.txt file2.txt

(1) 이것은 5 년 전의 Shâu Shắc의 답변 과 거의 동일합니다 . (2) 사용자가 vi한 번에 하나의 파일 만 호출한다고 가정합니다 . 작동하지 않습니다 vi file1 file2. (3) 사용자가로 다른 파일로 전환하면 :e처리되지 않는다는 것은 말할 나위도 없습니다.
G-Man, 'Reinstate

잊어 버려서 죄송합니다. 이제 Shâu Shắc의 답변에 참조 링크를 추가했습니다.
스틸리 윙

귀하의 질문 # 3에 대해, 다른 파일을 열면 명령 줄에없는 것이 문제라고 생각합니다.
스틸리 윙

1
내 요점은, 질문에 "vim이 원하는 방식으로 동작하게하려면 어떻게해야합니까?"라고 물으면 사용자가 원하는 방식으로 vim이 동작하는 것처럼 보이는 기능을 제공하는 것입니다. 대답. 좋아, 어쩌면 내 의견은 조금 불공평 할 수도 있지만, 다른 모든 대답은 동일한 제한을 가지고있는 것처럼 보이지만 내가 말할 수있는 한 그 대답은 언급하지 않습니다. 답변이 새로운 것이기 때문에 귀하의 답변을 검토하고있었습니다. 나는 다른 답변을 보는 데 많은 시간을 소비하지 않았습니다.
G-Man, 'Reinstate

1

다른 파일에서 타임 스탬프를 복사하는 옵션이 있습니다.

touch -m -r file_source file_target

예:

[oracle@es abc]$ ls -tlr
total 4
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
[oracle@es abc]$ echo "hi hi" > b
[oracle@es abc]$ ls -ltr
total 4
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
-rw-r--r--. 1 oracle oinstall   6 May 13 18:58 b
[oracle@es abc]$ touch -m -r aa.txt b
[oracle@es abc]$ ls -tlr
total 8
-rw-r--r--. 1 oracle oinstall   6 May  8 20:35 b
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
[oracle@es abc]$ cat b
hi hi

1

이 웹 페이지 에서 훌륭한 해결책을 찾았습니다. 솔루션 은 기존 수정 시간을 유지하면서 현재 파일을 저장하는 vim 함수를 만들고이 함수를 F4함수 키에 바인딩합니다 .

그러나 F4수정 시간이 변경되면 vim이 혼란스러워지기 때문에 원래 함수에 사소한 버그가 포함되어 동일한 파일에서 두 번 사용되는 경우 다음 경고를 트리거하는 것으로 나타났습니다 .

WARNING: The file has been changed since reading it!!!
Do you really want to write to it (y/n)?

운 좋게도 이것은 쉽게 고칠 수 있습니다. 타임 스탬프를 복원 한 후 파일을 다시로드하기 위해 원래 함수에 "편집"명령을 추가 했으므로 vim은 파일의 예상 수정 시간을 알고 있습니다.

이 버그 수정으로 수정 된 vim 함수는 다음과 같습니다 ~/.vimrc.

function! WriteSmall()
    let mtime = system("date -d @`stat -c %Y ".shellescape(expand('%:p')) . "`")
    write
    call system("touch --date='".mtime."' ".shellescape(expand('%:p')))
    edit
endfunction
map <F4> :call WriteSmall()<CR>

참고 : 이 기능의 GNU 버전에 의존 date, stat그리고 touch.


0

위에서 설명한 개념 중 일부를 사용하여 다음과 같은 목적으로 "편집"명령을 사용할 수있게하는 CSH에 대한 매우 빠르고 더러운 단일 라이너 별칭이 있습니다.

alias edit 'touch -r \!:1 /tmp/~mtime ; vim \!:1 ; touch -r /tmp/~mtime \!:1 ; rm /tmp/~mtime'

"vim"대신 $ VISUAL 또는 $ EDITOR 환경 변수를 쉽게 사용할 수 있습니다. 이 방법으로 다음 명령을 실행하여 기본 편집기를 변경할 수 있습니다

setenv VISUAL nano

이제 다른 편집기를 수용하기 위해 별명 자체를 다시 정의 할 필요가 없으므로 좀 더 이식성이 좋습니다. 물론 CSH 또는 TCSH 이외의 쉘을 사용하는 경우 위의 예를 적절히 조정할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.