รักษาการประทับเวลาที่แก้ไขหลังจากแก้ไข


20

สำหรับไฟล์ภายในโฟลเดอร์ที่เฉพาะเจาะจงฉันต้องการให้กลุ่มที่จะไม่สัมผัส "แก้ไข" เวลาประทับเลย

พื้นหลังคือฉันใช้Bloxsomสำหรับบล็อกซึ่งใช้ไฟล์ข้อความล้วน~/bloxsomเป็นแหล่งที่มาของบทความทั้งหมด วันที่ของบทความ (และลำดับของการปรากฏ) จะขึ้นอยู่กับวันที่แก้ไขของไฟล์ข้อความ ฉันไม่ต้องการให้บทความปรากฏขึ้นหากเป็นบทความใหม่เมื่อใดก็ตามที่ฉันเพิ่งพิมพ์ผิด (ฉันทำหลายอย่าง ... : D)

จนถึงการเปลี่ยนแปลงเป็นกลุ่มที่ประทับเวลาและประทับเดิมจะหายไปตลอดกาล ไม่เป็นไรและฉันต้องการให้เป็นเช่นนั้นสำหรับไฟล์ส่วนใหญ่ในระบบ แต่ฉันไม่ต้องการสิ่งนั้นสำหรับไฟล์บล็อก - ฉันสามารถtouchใช้ไฟล์ได้ตลอดเวลาถ้าต้องการ

ความคิดเห็นใด ๆ เกี่ยวกับวิธีปรับแต่งเสียงในพฤติกรรมนี้


2
vim.wikia.com/wiki/ ...... - คุณสามารถใช้การผูก perl แทนได้แน่นอน
Ulrich Dangel

คำตอบ:


22

ฉันไม่คิดว่ากลุ่มมีคุณสมบัตินี้ ทางเลือกหนึ่งคือแก้ไขสำเนาและตั้งเวลาประทับอย่างเหมาะสมเช่น:

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 สำหรับสิ่งนั้น

มันเป็นเสื้อคลุมรอบเสียงเรียกเข้าบันทึกไว้~/bin/vim-nomtime.plและนำไปใช้alias vim='~/bin/vim-nomtime.pl'ใน. bashrc ของฉัน

#!/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->{$_}, $_;
    }
}

คุณสมบัติที่ดีบางอย่าง:

  • รองรับหลายชื่อไฟล์

  • รองรับ dirs "ดู" หลายรายการ

  • รองรับ dir symlinked

  • สามารถปรับปรุงด้วยเกณฑ์อื่น ๆ

ซึ่งส่วนใหญ่สามารถทำได้ด้วยรุ่น vim ล้วนๆ ข้อเสียของโซลูชันนี้เปรียบเทียบกับโซลูชัน vim แบบบริสุทธิ์ที่ฉันต้องการคือ:

  • มันจะคืนค่าการประทับหลังจากที่ vim เลิกแล้วดังนั้นหากฉันทำการแก้ไขและบันทึกเป็นระยะเวลานานไฟล์ vill "pop-up" จะใหม่จนกว่าฉันจะออกจาก vim

  • มันรองรับไฟล์หลาย ๆ ไฟล์ในบรรทัดคำสั่ง แต่ในทางที่ไร้เดียงสา - มันจะตรวจสอบเฉพาะสิ่งที่@ARGVเป็นไฟล์ สิ่งนี้อาจไม่ทำงานกับ wildcard (เช่นvim note-*.txt) หรือสิ่งตลกอื่น ๆ

  • มันไม่ได้เป็นข้อผิดพลาดในการพิสูจน์อาจไม่ได้เป็น HUP-proof (สามารถทำได้)

  • ... เวลมันเป็นเสื้อคลุม (ฉันหมายถึงถ้าเราแก้ไขทุกอย่างผ่านทาง wrapper เราจะมีตัวห่อไว้กี่อันก่อนที่จะมีสิ่งเลวร้ายเกิดขึ้น?)


3 พฤษภาคม 2019 และฉันเพิ่งแก้ไขไฟล์จาก 11 พฤศจิกายน 2017 และมันมีทั้งการดัดแปลงของฉันและเก็บบันทึกเวลาดั้งเดิม :)
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âuShắ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) นี่เกือบจะเหมือนกับคำตอบของShâuShắcเมื่อห้าปีที่แล้ว (2) สิ่งนี้จะถือว่าผู้ใช้ทำการเรียกใช้viไฟล์ครั้งละหนึ่งไฟล์เท่านั้น vi file1 file2มันจะไม่ทำงาน (3) มันจะไปโดยไม่บอกว่าถ้าผู้ใช้สลับไปยังไฟล์อื่นด้วย:eมันจะไม่ถูกจัดการ
G-Man กล่าวว่า 'Reinstate Monica'

ขออภัยที่ลืมอ้างอิงตอนนี้ฉันได้เพิ่มลิงก์อ้างอิงไปยังคำตอบของShâuShắc
Steely Wing

เกี่ยวกับคำถาม # 3 ของคุณฉันคิดว่าถ้าคุณเปิดไฟล์อื่นไม่ได้อยู่ในบรรทัดคำสั่งนั่นเป็นปัญหาของคุณ
Steely Wing

1
ประเด็นของฉันคือถ้าคำถามถามว่า "ฉันจะทำให้กลุ่มทำงานในแบบที่ฉันต้องการได้อย่างไร" และคุณจัดเตรียมฟังก์ชั่นที่ดูเหมือนว่ากลุ่มนั้นกำลังทำหน้าที่เป็นกลุ่มตามที่ผู้ใช้ต้องการมันเป็นความรับผิดชอบของคุณ ตอบ. ตกลงบางทีความคิดเห็นของฉันอาจไม่ยุติธรรมนัก แต่คำตอบอื่น ๆ ดูเหมือนจะมีข้อ จำกัด เหมือนกันและไม่มีใครพูดถึงมันเท่าที่ฉันสามารถบอกได้ ฉันแค่ทบทวนคำตอบของคุณเพราะมันใหม่ ฉันไม่ได้ใช้เวลามากมายในการดูคำตอบอื่น ๆ
G-Man กล่าวว่า 'Reinstate Monica'

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

ฉันพบทางออกที่ยอดเยี่ยมใน หน้าเว็บนี้ซึ่งสร้างฟังก์ชั่นเป็นกลุ่มเพื่อบันทึกไฟล์ปัจจุบันในขณะที่รักษาเวลาการแก้ไขที่มีอยู่และผูกฟังก์ชันนี้กับF4คีย์ฟังก์ชัน:

อย่างไรก็ตามฉันพบว่าฟังก์ชั่นดั้งเดิมมีข้อผิดพลาดเล็กน้อยเรียกใช้คำเตือนต่อไปนี้หากF4ใช้สองครั้งในไฟล์เดียวกันเพราะเสียงเรียกเข้าจะสับสนเมื่อเวลาการแก้ไขเปลี่ยนแปลง:

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

โชคดีที่มันเป็นเรื่องง่ายที่จะแก้ไข: ฉันเพิ่มคำสั่ง "แก้ไข" ในฟังก์ชั่นเดิมเพื่อโหลดไฟล์ใหม่หลังจากเรียกคืนเวลาประทับดังนั้นกลุ่มจึงรู้ว่าเวลาแก้ไขใดที่คาดว่าจะมีไฟล์

นี่คือฟังก์ชั่น 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, และstattouch


0

ใช้แนวคิดบางอย่างที่อธิบายไว้ข้างต้นนี่คือนามแฝงแบบหนึ่งซับที่รวดเร็วและสกปรกสำหรับ CSH ที่ทำให้คำสั่ง "แก้ไข" พร้อมใช้งานสำหรับวัตถุประสงค์นี้:

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

คุณสามารถใช้ตัวแปรสภาพแวดล้อม $ VISUAL หรือ $ EDITOR แทน "vim" ได้อย่างง่ายดาย วิธีนี้คุณสามารถใช้คำสั่งต่อไปนี้เพื่อเปลี่ยนโปรแกรมแก้ไขเริ่มต้น

setenv VISUAL nano

ตอนนี้นามแฝงเองไม่จำเป็นต้องถูกนิยามใหม่เพื่อรองรับบรรณาธิการที่แตกต่างกันทำให้มันค่อนข้างพกพามากขึ้น หากคุณใช้เชลล์อื่นที่ไม่ใช่ CSH หรือ TCSH แน่นอนตัวอย่างข้างต้นสามารถปรับเปลี่ยนได้ตามความเหมาะสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.