किसी फ़ाइल में रीयलटाइम परिवर्तनों की निगरानी कर सकते हैं


104

मेरा प्रश्न इस के समान है कि कैसे वास्तविक समय में एक पाठ फ़ाइल की निगरानी करें लेकिन मैं इसे व्यर्थ में करना चाहता हूं। मुझे पता है कि मैं एक खोला फ़ाइल उपयोग tail -f sample.xmlफ़ाइल पढ़ सकता हूं , और जब नई सामग्री फ़ाइल में लिखी जाती है, तो यह मेरी स्क्रीन पर नई सामग्री भी लिख देगी। क्या किसी फ़ाइल के अपडेट होने पर मैं अपने आप नया डेटा भर सकता हूँ?

जवाबों:


101

जब आप :set autoreadफ़ाइल को बदलते हैं तो आप उसे पढ़ सकते हैं। हालाँकि (आपके प्लेटफ़ॉर्म के आधार पर), आपको इसे फ़ोकस करना होगा।

मदद से:

जब कोई फ़ाइल विम के बाहर बदल दी गई है, तो उसे विम के अंदर नहीं बदला गया है, स्वचालित रूप से उसे फिर से पढ़ें। जब फ़ाइल को हटा दिया गया है तो ऐसा नहीं किया जाता है।


5
संकेत के लिए धन्यवाद! यह बहुत ही आशाजनक लग रहा है, लेकिन यह मेरे सिस्टम पर काम नहीं करता है :( मैं mac10.6.2 का उपयोग कर रहा हूँ। वीर संस्करण 7.2.303 के साथ iTerm मैकविम के साथ संकलित किया गया है। कोई अतिरिक्त टिप्पणी मैं कोशिश कर सकता हूं?
पैट्रिक

erm, यह बहुत अजीब है। क्या आप macvim gui या टर्मिनल संस्करण का उपयोग कर रहे हैं? यह मेरे लिए काम करता है macvim gui डाउनलोड precompiled के साथ। (मुझे ध्यान देने के लिए ऐप पर क्लिक करना होगा, जैसा कि मैंने उल्लेख किया है।)
पीटर

1
मैं टर्मिनल में परीक्षण कर रहा था, जब मैंने gvim (MacVim GUI) का उपयोग किया, तो कार्य करना शुरू हो गया! जैसा कि आपने उल्लेख किया है, लेकिन मुझे सामग्री को अपडेट करने के लिए जीवीएम पर ध्यान केंद्रित करने की आवश्यकता है। क्या आपके पास ध्यान केंद्रित किए बिना भी इसे अपडेट करने की कोई चाल है? आपने जो मदद दी उसके लिए फिर से धन्यवाद।
पैट्रिक

3
मैं दुर्भाग्य से इसका हल नहीं जानता। अगर कोई फ़ोकस बदलने के बिना विम कर सकता है, तो मैं दंग रह जाऊँगा - यह बदलने के लिए फाइलसिस्टम को देखने के लिए विम की आवश्यकता होगी। मुझे लगता है कि आपको इसके लिए एक प्लगइन की आवश्यकता होगी।
पीटर

2
@Peter मैंने कुछ समय पहले ऐसा प्लगइन बनाया था। इस प्रश्न और इसके उत्तर के बारे में भी देखें । कैसे autoreadकाम करता है और इसकी सीमाओं के बारे में अधिक जानकारी के लिए ।
मार्टिन टूरनोइज

63

स्वचालित रूप से नहीं जानते, लेकिन आप टाइप कर सकते हैं:

:e!

फ़ाइल को फिर से लोड करने के लिए


यद्यपि यह दृष्टिकोण सामग्री को ऑटो अपडेट नहीं करता है, लेकिन यह अपडेट की गई सामग्री को प्रदर्शित करता है। आपके उत्तर के लिए धन्यवाद!
पैट्रिक

31

निम्नलिखित को अपने में रखें .vimrc:

"सामान्य मोड में 4 जी निष्क्रियता के बाद एक बार जांचें
ऑटोराइड सेट करें                                                                                                                                                                                    
au CursorHold * चेकटाइम                                                                                                                                                                       

महान! अच्छी तरह से काम करता है, यहां तक ​​कि एक चेतावनी के साथ यदि आपने पिछले रिलोडिंग के बाद से उस फ़ाइल को बदल दिया है।
५ou बजे

1
पहला जवाब मेरे लिए काम नहीं किया, लेकिन यह काम करता है! :-)
इओनिको बिजुआ

4
"हर 4 सेकंड" सच नहीं है। यह सामान्य मोड में 4 जी निष्क्रियता के बाद केवल एक बार जांच करेगा । इसलिए यदि आप लंबे समय तक किसी अन्य बफर में कुछ भी नहीं करते हैं, तो इसे अपडेट नहीं किया जाएगा, लेकिन यदि आप कर्सर को ले जाते हैं और 4 जी की प्रतीक्षा करते हैं। एक अन्य विकल्प मैन्युअल रूप से कॉल करने के लिए है ": चेकटाइम" अपडेट करने के लिए (ऑटोराइड सेट करने के बाद)। दुर्भाग्य से वहाँ किसी भी तरह का मतदान समर्थन नहीं प्रतीत होता है, इसलिए ओपी प्रश्न का कोई सही उत्तर नहीं है।
डेविड लजंग मैडिसन स्टेलर

1
बस इसी के साथ आया था। यदि आप एक कस्टम फ़ंक्शन को कॉल करने के लिए चेकटाइम बदलते हैं और फ़ंक्शन के अंत में "कॉल फीडकी (" lh ")" जोड़ते हैं तो यह हर 4 सेकंड में आग लगा देगा।
flukus

@DavidLjungMadison आप सही हैं, मैं इस गलती से बचने के लिए पोस्ट को संपादित करने जा रहा हूं
फान है क्वांग

9

जैसे @flukus ने आपके पिछले उत्तर के लिए एक टिप्पणी में कहा था call feedkeys["lh"](यह कर्सर को दाईं ओर और बाईं ओर पीछे ले जाता है, जो सामान्य रूप से लॉग फ़ाइल देखने पर नुकसान नहीं करता है)

इसलिए, यदि आप शेष उत्तर को जोड़ते हैं, तो आपके पास एक oneliner है जिसे आप आवश्यकता होने पर पूर्व (whithin vim) से चला सकते हैं:

:set autoread | au CursorHold * checktime | call feedkeys("lh")


(यदि आप फ़ाइल के अंत में कूदना चाहते हैं (लगभग), तो बस "एलएच" के बजाय "एल" का उपयोग करें।

स्पष्टीकरण:
- ऑटोरैड : फ़ाइल को तब पढ़ा जाता है जब उसे बाहर से बदला जाता है (लेकिन यह अपने आप काम नहीं करता है, कोई आंतरिक टाइमर या ऐसा कुछ नहीं है। यह केवल फ़ाइल को पढ़ेगा जब विम एक्शन करता है, जैसे पूर्व में एक कमांड :!
- CursorHold * checktime : जब कर्सर को 'updatetime' में निर्दिष्ट समय के लिए उपयोगकर्ता द्वारा स्थानांतरित नहीं किया जाता है (जो कि डिफ़ॉल्ट रूप से 4000 मील के सेकंड है) चेकटाइम निष्पादित किया जाता है, जो फ़ाइल के बाहर से परिवर्तन की जांच करता है
- कॉल फीडकी ("lh") : कर्सर को एक बार दाएं और बाएं घुमाया जाता है और फिर कुछ नहीं होता है (... जिसका अर्थ है, कि CursorHold ट्रिगर है, जिसका अर्थ है कि हमारे पास एक लूप है )

इसके अतिरिक्त आप :set syntax=logtalkलॉग को रंग कर सकते हैं

उपयोग करते समय स्क्रॉल को रोकने के लिए call feedkeys("G"), निष्पादित करें :set noautoread- अब vim बताएगा, कि फ़ाइल में परिवर्तन था ans पूछें कि क्या कोई बदलाव पढ़ना चाहता है या नहीं)

(क्या इसका कोई साइडइफेक्ट है?)

संपादित करें: मुझे एक साइड-इफ़ेक्ट दिखाई देता है: अगर कोई फीडर से "G" का उपयोग करता है, तो यह हर वर्तमान में खोले गए बफर को नीचे स्क्रॉल करेगा ?! इसलिए, सही बफ़र को स्वचालित रूप से लॉगफ़ाइल नीचे स्क्रॉल करते समय एक स्प्लिट विंडो के बाएं बफर में काम करना संभव नहीं है


4

इसे अपने .vimrc में चिपकाएं और इसे बॉस की तरह काम करना चाहिए। (इससे लिया गया: http://vim.wikia.com/wiki/Have_Vim_check_automatically_if_the_file_has_changed_externally )

" Function to Watch for changes if buffer changed on disk
function! WatchForChanges(bufname, ...)
  " Figure out which options are in effect
  if a:bufname == '*'
    let id = 'WatchForChanges'.'AnyBuffer'
    " If you try to do checktime *, you'll get E93: More than one match for * is given
    let bufspec = ''
  else
    if bufnr(a:bufname) == -1
      echoerr "Buffer " . a:bufname . " doesn't exist"
      return
    end
    let id = 'WatchForChanges'.bufnr(a:bufname)
    let bufspec = a:bufname
  end
  if len(a:000) == 0
    let options = {}
  else
    if type(a:1) == type({})
      let options = a:1
    else
      echoerr "Argument must be a Dict"
    end
  end
  let autoread    = has_key(options, 'autoread')    ? options['autoread']    : 0
  let toggle      = has_key(options, 'toggle')      ? options['toggle']      : 0
  let disable     = has_key(options, 'disable')     ? options['disable']     : 0
  let more_events = has_key(options, 'more_events') ? options['more_events'] : 1
  let while_in_this_buffer_only = has_key(options, 'while_in_this_buffer_only') ? options['while_in_this_buffer_only'] : 0
  if while_in_this_buffer_only
    let event_bufspec = a:bufname
  else
    let event_bufspec = '*'
  end
  let reg_saved = @"
  "let autoread_saved = &autoread
  let msg = "\n"
  " Check to see if the autocommand already exists
  redir @"
    silent! exec 'au '.id
  redir END
  let l:defined = (@" !~ 'E216: No such group or event:')
  " If not yet defined...
  if !l:defined
    if l:autoread
      let msg = msg . 'Autoread enabled - '
      if a:bufname == '*'
        set autoread
      else
        setlocal autoread
      end
    end
    silent! exec 'augroup '.id
      if a:bufname != '*'
        "exec "au BufDelete    ".a:bufname . " :silent! au! ".id . " | silent! augroup! ".id
        "exec "au BufDelete    ".a:bufname . " :echomsg 'Removing autocommands for ".id."' | au! ".id . " | augroup! ".id
        exec "au BufDelete    ".a:bufname . " execute 'au! ".id."' | execute 'augroup! ".id."'"
      end
        exec "au BufEnter     ".event_bufspec . " :checktime ".bufspec
        exec "au CursorHold   ".event_bufspec . " :checktime ".bufspec
        exec "au CursorHoldI  ".event_bufspec . " :checktime ".bufspec
      " The following events might slow things down so we provide a way to disable them...
      " vim docs warn:
      "   Careful: Don't do anything that the user does
      "   not expect or that is slow.
      if more_events
        exec "au CursorMoved  ".event_bufspec . " :checktime ".bufspec
        exec "au CursorMovedI ".event_bufspec . " :checktime ".bufspec
      end
    augroup END
    let msg = msg . 'Now watching ' . bufspec . ' for external updates...'
  end
  " If they want to disable it, or it is defined and they want to toggle it,
  if l:disable || (l:toggle && l:defined)
    if l:autoread
      let msg = msg . 'Autoread disabled - '
      if a:bufname == '*'
        set noautoread
      else
        setlocal noautoread
      end
    end
    " Using an autogroup allows us to remove it easily with the following
    " command. If we do not use an autogroup, we cannot remove this
    " single :checktime command
    " augroup! checkforupdates
    silent! exec 'au! '.id
    silent! exec 'augroup! '.id
    let msg = msg . 'No longer watching ' . bufspec . ' for external updates.'
  elseif l:defined
    let msg = msg . 'Already watching ' . bufspec . ' for external updates'
  end
  echo msg
  let @"=reg_saved
endfunction

let autoreadargs={'autoread':1}
execute WatchForChanges("*",autoreadargs)

1
यह टर्मिनल ऑटोरैड कमियों को संबोधित करने के लिए पसंदीदा उत्तर है।
mcanfield

3
@mcanfield नहीं, यह नहीं है क्योंकि यह अभी भी "परिवर्तनों के लिए नहीं देखता है"। आपको अभी भी विम को सक्रिय करने की आवश्यकता है और यह अभी भी घटनाओं के सीमित सेट पर मतदान (देख नहीं रहा है) कर रहा है। CursorHoldएक बार चलाया जाता है । इसलिए यदि आप बाहर जाते हैं और कॉफी पीते हैं, या दूसरी विंडो में कुछ कर रहे हैं तो यह अपडेट नहीं होगा ।
मार्टिन टूरनोइज

4
उस स्क्रिप्ट को Vim plugin: vim-autoread के रूप में भी बंडल किया गया है ।
Stephen.hanson

1
@ stephen.hanson लिंक के लिए धन्यवाद, वह प्लगइन मेरे लिए अच्छा काम कर रहा है!
ट्रोपिलियो


2

अगर यूनिक्स + नवविराम

:term tail -f <filename>

जाहिर है कि यह सभी के लिए काम नहीं करेगा, लेकिन यह है कि मैं इसे कैसे करता हूं।



0

जब कोई फ़ाइल अपडेट की जाती है तो VIM आपको चेतावनी देगा कि आपने इसे खोलने के बाद से किए गए परिवर्तनों को अधिलेखित नहीं किया है। यह आपको उस बिंदु पर फ़ाइल पुनः लोड करने के लिए संकेत देगा।


1
आपके उत्तर के लिए धन्यवाद, लेकिन विम ने मुझे चेतावनी नहीं दी जब मेरे सिस्टम में फ़ाइल बदल दी गई थी :(
पैट्रिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.