संपादित किए जाने के बाद संशोधित समय स्टाम्प को संरक्षित करें


20

एक विशिष्ट फ़ोल्डर में फ़ाइलों के लिए, मैं कभी भी "संशोधित" टाइमस्टैम्प को स्पर्श नहीं करना चाहूंगा।

पृष्ठभूमि यह है कि मैं ब्लॉगिंग के लिए ब्लॉक्स का उपयोग करता हूं , जो ~/bloxsomसभी लेखों के स्रोत के रूप में सादे पाठ फ़ाइलों का उपयोग करता है । लेख की तारीख (और इसलिए उपस्थिति का आदेश) पाठ फ़ाइल के संशोधन की तारीख पर आधारित है। मैं लेख को पॉप अप नहीं करना चाहता अगर यह नया है जब भी मैं सिर्फ एक टाइपो को ठीक करता हूं। (मैं उनमें से बहुत कुछ ...: डी)

अब तक, विम टाइमस्टैम्प को बदल देता है और मूल टिकट हमेशा के लिए खो जाता है। यह ठीक है और मैं इसे सिस्टम की अधिकांश फाइलों के लिए रखना चाहता हूं। लेकिन मैं नहीं चाहता कि ब्लॉग फ़ाइलों के लिए - मैं हमेशा touchफ़ाइल को ज़रूरत पड़ने पर रख सकूँ ।

कैसे इस व्यवहार में विम के लिए कोई विचार?


2
vim.wikia.com/wiki/… - आप निश्चित रूप से इसके बजाय पर्ल बाइंडिंग का उपयोग कर सकते हैं
उलरिच डेंगल

जवाबों:


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

मैंने उसके लिए एक पर्ल स्क्रिप्ट लिखी।

यह विम के चारों ओर एक आवरण है, इसमें सहेजा गया है ~/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->{$_}, $_;
    }
}

कुछ अच्छी विशेषताएं:

  • कई फ़ाइल नाम का समर्थन करता है

  • कई "देखे गए" डायर का समर्थन करता है

  • सहिष्णु dir का समर्थन करता है

  • अन्य मानदंडों के साथ बढ़ाया जा सकता है

जिनमें से अधिकांश को शायद शुद्ध विम संस्करण के साथ भी हासिल किया जा सकता है। मेरे इच्छित शुद्ध-विम समाधान की तुलना में इस समाधान के नुकसान इस प्रकार हैं:

  • vim के निकलने के बाद ही यह स्टाम्प को पुनर्स्थापित करता है , इसलिए यदि मैं एक लंबा संपादन करता हूं और नियमित रूप से सहेजता हूं, तो फ़ाइल "pop-up" नए के रूप में जब तक मैं vim नहीं छोड़ता

  • यह कमांड लाइन पर कई फाइलों का समर्थन करता है, लेकिन काफी भोले तरीके से - यह केवल जांचता है कि क्या चीज @ARGVएक फाइल है। यह संभवतः वाइल्डकार्ड (जैसे vim note-*.txt) या अन्य मज़ेदार सामान के साथ काम नहीं करेगा

  • यह क्रैश प्रूफ नहीं है, शायद HUP प्रूफ भी नहीं है (जो किया जा सकता है)

  • ... स्वागत है, यह एक आवरण है। (मेरा मतलब है, अगर हमने रैपर के माध्यम से सब कुछ हल कर लिया, तो कुछ खराब होने से पहले हमारे पास कितने रैपर होंगे?)


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फ़ंक्शन का प्रयास करें ( Shuu 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

(१) यह पाँच साल पहले के Shuu Sh'sc के उत्तर के लगभग समान है । (२) यह मानता है कि उपयोगकर्ता viएक बार में केवल एक ही फाइल पर आक्रमण करता है ; यह काम नहीं करेगा vi file1 file2। (३) यह कहे बिना जाता है कि, यदि उपयोगकर्ता किसी भिन्न फ़ाइल के साथ स्विच करता है :e, तो उसे संभाला नहीं जाएगा।
जी-मैन का कहना है कि 'मोनिका'

संदर्भ के लिए क्षमा करें, अब मैंने Shuu Sh answerc के उत्तर के लिए एक संदर्भ लिंक जोड़ा।
स्टीली विंग

आपके प्रश्न # 3 के बारे में, मुझे लगता है कि यदि आप एक और फाइल खोलते हैं, तो कमांड लाइन में नहीं है, यह आपकी समस्या है।
स्टेली विंग

1
मेरी बात यह है कि, यदि प्रश्न पूछता है कि "मैं अपनी इच्छा के अनुसार व्यवहार कैसे कर सकता हूं?" जवाब। ठीक है, हो सकता है कि मेरी टिप्पणी थोड़ी अनुचित है, क्योंकि अन्य सभी उत्तर एक ही सीमा के लगते हैं, और उनमें से कोई भी इसका उल्लेख नहीं करता है, जहां तक ​​मैं बता सकता हूं। मैं आपके उत्तर की समीक्षा कर रहा था क्योंकि यह नया था; मैं अन्य उत्तरों को देखने में बहुत समय खर्च नहीं करता था।
जी-मैन का कहना है कि 'मोनिका'

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एक ही फ़ाइल पर दो बार उपयोग किया जाता है, क्योंकि संशोधन समय बदलने पर विम भ्रमित हो जाता है:

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

सौभाग्य से, इसे ठीक करना आसान है: मैंने टाइमस्टैम्प को पुनर्स्थापित करने के बाद फ़ाइल को फिर से लोड करने के लिए मूल फ़ंक्शन में एक "एडिट" कमांड जोड़ा, इसलिए विम को पता है कि फ़ाइल के पास होने के लिए क्या संशोधन समय है।

यहाँ इस बग फिक्स के साथ संशोधित विम फ़ंक्शन है, जिसे इसमें जोड़ा जा सकता है ~/.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'

आप "विम" के स्थान पर $ VISUAL या $ EDITOR पर्यावरण चर का उपयोग आसानी से कर सकते हैं। इस तरह आप डिफ़ॉल्ट संपादकों को बदलने के लिए निम्न आदेश जारी कर सकते हैं

setenv VISUAL nano

अब उर्फ ​​खुद को अलग-अलग संपादकों को समायोजित करने के लिए फिर से परिभाषित करने की आवश्यकता नहीं है, जिससे यह कुछ हद तक पोर्टेबल हो जाता है। यदि आप CSH या TCSH के अलावा किसी अन्य शेल का उपयोग करते हैं, तो निश्चित रूप से, ऊपर दिए गए उदाहरणों को तदनुसार अनुकूलित किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.