संख्याओं के एक कॉलम की कुल गणना करें


15

मैं एक मार्कडाउन तालिका लिख ​​रहा हूँ जो इस प्रकार है:

| 13/05/15 | 09:30-16:00 |  6.5 |
| 14/05/15 | 10:00-16:30 |  6.5 |
| 16/05/15 | 15:30-01:00 |  9.5 |
| 21/05/15 | 09:00-16:30 |  7.5 |
| 22/05/15 | 08:30-17:00 |  8.5 |
| 28/05/15 | 09:30-15:30 |  6   |
| 02/06/15 | 09:00-20:00 | 11   |
| 03/06/15 | 08:30-22:30 | 14   |

मैं तीसरे कॉलम के कुल की गणना करने और इसे बफर में डालने का एक तरीका ढूंढ रहा हूं। मेरे पास जो समाधान है वह दृश्य-ब्लॉक मोड (सभी संख्याओं का चयन करने के लिए) और शायद अभिव्यक्ति रजिस्टर (गणित करने के लिए) का उपयोग करेगा।

क्या यह देशी विम कमांड्स के उपयोग से संभव होगा? यदि नहीं, तो क्या कोई प्लगइन है जो मेरी मदद कर सकता है?


1
आप इस लेख पर नज़र डाल सकते हैं: vim.wikia.com/wiki/Using_vim_as_calculator
nobe4

जवाबों:


15

मैंने एक प्लगइन लिखा: https://github.com/sk1418/HowMuch जो दृश्य चयन का समर्थन करता है और गणित की गणना करता है।

डिफ़ॉल्ट रूप से प्लगइन तीन गणित-अभिव्यक्ति मूल्यांकन इंजन का समर्थन करता है: ग्नू बीसी, अजगर, और विम्सस्क्रिप्ट। आप एक निश्चित एक पर गणना कर सकते हैं या प्लगइन को स्वचालित रूप से आपके लिए एक चुनने दें।

यह आपके उदाहरण के साथ इस तरह काम करता है:

यहाँ छवि विवरण दर्ज करें

जानकारी के लिए कृपया पढ़ें GADUB पर README।


यदि आप अपने उत्तर में चयन, योग और सम्मिलित करने के लिए आवश्यक कीस्ट्रोक्स शामिल करेंगे तो यह उपयोगी होगा।
पोद्दहरी

@ pdoherty926 For details please read the README on github.अगर मैं यहां इस समस्या के लिए दबाए गए कीस्ट्रोक्स लगाता हूं, तो मैं यह नहीं देखता कि यह कितना उपयोगी हो सकता है, यह सिर्फ 3 या 4 कुंजी-संयोजन है। अगर मेरी स्क्रिप्ट की किसी को वास्तव में ज़रूरत है, तो वह वैसे भी विवरण की जाँच करेगा।
कैंट

12

यदि आप प्लग-इन का उपयोग नहीं करना चाहते हैं या किसी bash स्क्रिप्ट को छोड़ना चाहते हैं, तो आप निम्न की तरह कुछ कर सकते हैं:

  • c-V {motions} "ay कॉलम कॉपी करें "a
  • :let @a = substitute(@a, 'c-V c-J', '+', 'g') कॉलम के साथ नई सुर्खियों को बदलें +
  • ic-R=c-Ra"aअभिव्यक्ति रजिस्टर के माध्यम से प्रतिस्थापित किया

वैकल्पिक रूप से: स्तंभों के आगे के योगों के लिए अभिव्यक्ति इतिहास प्रविष्टि को पुन: प्रयोज्य बनाएं

  • ctrl-V {motions} y कॉलम को यैंक रजिस्टर में डालें ""
  • ictrl-R=eval(substitute(@", '\n', '+', 'g'))

दूसरे कॉलम के लिए दोहराव:

  • ctrl-V {motion} y (अपरिवर्तित)
  • ictrl-R=<CR>या यदि आपने अभिव्यक्ति रजिस्टर के साथ कुछ और किया है, तो ऊपर तीर कुंजी के साथ इतिहास के माध्यम से चक्र करें (या ctrl-Pयदि आपने इसे हटा दिया है तो):
    ictrl-R=<up>...<up><CR>

1
किसी कारण से मैं केवल कमांड पर "सिंगल कोट्स के बजाय डबल कोट्स के साथ आपके समाधान का उपयोग करने में कामयाब रहा । क्या आप जानते हैं कि क्या इसका कोई कारण है? 'substitute
वॅपकिनारियो 19

@vappolinario यह मेरे लिए दोनों तरह से काम करता है, इसलिए मुझे डर है कि मुझे नहीं पता, माफ करना।
होवरकॉच

@ होवरकॉच क्या आप तीसरे चरण पर विस्तार से बता सकते हैं? कैसे, वास्तव में, एक अभिव्यक्ति रजिस्टर के माध्यम से प्रतिस्थापन को चलाने के बारे में क्या होगा?
pdoherty926 16

मानचित्र बनाने के बारे में: `nnoremap <cs>: s / $ / \ = eval (स्थानापन्न (@ 0, '[^ 0-9]', '+', 'g')) / <cr>`
Sergio_raujo

9
:r!awk '{sum+=$6} END {print "Total: "sum}' %

स्पष्टीकरण:

:r ........... read (put result in this file)
! ............ external command
awk .......... external tool
{sum+=$6} .... sixth field (awk considers spaces as field separator)
END .......... at the end
{print "Total: "sum} --> string "Total: " plus your result
% ............ current file

मैं यहाँ काम करने वाले एक फंक्शन की कोशिश कर रहा हूँ:

" This function requires you select the numbers
fun! SumVis()
    try
        let l:a_save = @a
        norm! gv"ay
        let @a = substitute(@a,'[^0-9. ]','+','g')
        exec "norm! '>o"
        exec "norm! iTotal \<c-r>=\<c-r>a\<cr>"
     finally
        let @a = l:a_save
     endtry
endfun
vnoremap <leader>s :<C-u>call SumVis()<cr>

ऊपर दिए गए नक्शे का उपयोग करते हुए, आपको लोडिन के बाद सभी कार्य करना है फ़ंक्शन का चयन करना है जो संख्या आप योग करना चाहते हैं और <leader>sचयनित क्षेत्र को योग करने के लिए उपयोग करना चाहते हैं।

समारोह स्पष्टीकरण:

यह try/finally/endtryत्रुटियों को पकड़ने के लिए एक्सट्रक्चर का उपयोग करता है ।

let l:a_save = @a .......... if whe have register 'a' we save it temporarelly
norm! gv"a  ................................... gv --> reselects and captures selection to 'register a'
let @a = substitute(@a,'[^0-9. ]','+','g') .... removes all but numbers, dots and spaces from 'register a' and puts '+' among the numbers
exec "norm! '>o"  ............................. opens new line bellow selection. see :h '>
exec "norm! iTotal: \<c-r>=\<c-r>a\<cr>" ...... insert "Total: " plus 'expression register result
let @a = l:a_save ............................. restores original 'a' register content

यदि आप इस फ़ंक्शन को आज़माना चाहते हैं, तो निम्न कार्य करें: अपने ब्राउज़र में इस फ़ंक्शन को कॉपी करें और इस कमांड को vim पर चलाएं इससे :@+ आप :call SumVis()सामान्य रूप से उपयोग कर पाएंगे ।

:@+ ......... loads `+` register making the function avaiable

यह आपको ctrl+ के साथ एक दृश्य ब्लॉक चयन करने की आवश्यकता है v, अचयनित करें और अंत में फ़ंक्शन को कॉल करें। या आप सुझाए गए नक्शे का उपयोग कर सकते हैं जो गणना से पहले चयन को स्वयं हटा देता है।



5

एक प्लगइन बनाने या इस vimscript में कोडिंग थोड़ा भारी लगता है। मैं एक प्लगइन-मुक्त विम और बाहरी उपकरणों के साथ अच्छी रचना में विश्वास करता हूं।

यहां उपयोगकर्ता -2571881 के आधार पर 1-टाइम कमांड दी गई है, भले ही बफर सेव न किया गया हो।

:%!awk -F '|' '{print; sum+=$4}; END {print "Total: "sum}'

यदि आप भविष्य में उपयोग के लिए इस कमांड को सहेजना चाहते हैं, तो आप इसे नाम देना चाह सकते हैं:

:command! -range=% -nargs=1 SumColumn <line1>,<line2>!awk -F '|' '{print; sum+=$('<args>' + 1)} END {print "Total: "sum}'

यह दृश्य चयन के साथ काम करता है। यदि आप कुछ पंक्तियों का चयन करते हैं और कमांड मोड में जाते हैं, तो vim आपकी कमांड के साथ उपसर्ग करेगा :'<,'>, जो दृश्य चयन के लिए लाइन रेंज है। तो आप चला सकते हैं:

:'<,'>SumColumn 3

और यह चयनित पंक्तियों के केवल 3 कॉलम को समेटेगा। डिफ़ॉल्ट रूप से सीमा है %, इसलिए

:SumColumn 3

सभी पंक्तियों के 3 कॉलम का योग करेगा।

संपादित करें: यदि आप अन्य क्षेत्र विभाजकों को निर्दिष्ट करने में सक्षम होना चाहते हैं और अंतिम एक पर दिए गए कॉलम को डिफ़ॉल्ट करना चाहते हैं, तो आप कमांड को इसमें शामिल कर सकते हैं bashऔर इसके साथ तर्कों को संभाल सकते हैं, जैसे:

:command! -range=% -nargs=* SumColumn <line1>,<line2>!bash -c 'awk -F ${2:-|} "{print; sum+=\$(${1:-NF - 2} + 1)} END {print \"Total: \"sum}"' sumcolumn <args>

अभी,

:SumColumn

"" | " फ़ील्ड विभाजक,

:SumColumn 3

"|" क्षेत्र विभाजक, और

:SumColumn 3 +

"+" फ़ील्ड विभाजकों के साथ एक तालिका के तीसरे स्तंभ की गणना करेगा।


अन्य संभावित क्षेत्र विभाजकों से कोई कैसे निपट सकता है? बस समाधान को और अधिक सामान्य बनाने के लिए।
सर्जियोअराज़ो

@ user2571881, मैंने जवाब दिखा दिया है, यह दिखाते हुए।
जोएल

@JoL जैसे फंक्शन जोड़ने का SumColumnमतलब है कि आपके पास अपने वाइम आर्क में बस 'प्लगइन्स' हैं। उम्मीद है, आप इसे समय के साथ बनाए रखने में अच्छे होंगे। मेरे लिए प्लगइन्स प्रलेखन प्रदान करते हैं, सार्थक भागों में अलग हो जाते हैं, दूसरों की सरलता का लाभ उठाते हैं। मैं अपस्ट्रीम में योगदान देता हूं जो अद्भुत प्लगइन्स को बेहतर बनाता है जिसके पास किसी को भी अपने दम पर (tpope को छोड़कर) बनाने का समय नहीं है। क्या आप vim-go, vim-fugitive, vim-easy-align / vim-lion, vim-unimpaired, vim-commentary, ultisnips या ft-specific वाले जैसे vim-go, vim-rails, vimtex का उपयोग नहीं करते हैं?
होट्सचेक

@ हत्शके जब मैं यहाँ गया, मैंने सवाल देखा और सोचा, "ठीक है, बस जाग के माध्यम से पाइप।" लेकिन फिर, मैंने देखा कि स्वीकृत उत्तर था, "हे, इस सैकड़ों एलओसी प्लगइन डाउनलोड करें और इसे स्थापित करें।" तीसरा जवाब था, "अरे, यह हजारों LOC प्लगइन डाउनलोड करें और इसे स्थापित करें।" यह ओवरकिल और ब्लोट है। यहां तक ​​कि अगर आपको अपने जीवन में एक से अधिक बार कॉलम की जरूरत है, तो यह ओवरकिल है। मेरा जवाब यह दिखाने के लिए है कि आप इसे एक ही नो-प्लग इन, नो-नॉनसेंस कमांड में कैसे कर सकते हैं, यदि आपको केवल एक बार ऐसा करने की आवश्यकता है, और यदि आप इसे करने की आवश्यकता है, तो आप इसे से बाहर पैरामीटर के साथ एक साधारण कमांड कैसे बना सकते हैं। अक्सर।
JoL

@Hotchke आपके प्रश्न का उत्तर देने के लिए, मैं हर प्लगइन को सूरज के नीचे स्थापित करता था जो दूर से शांत दिखता था, लेकिन तब मेरा विम अविश्वसनीय रूप से धीमा था ("थोड़ा सा अंतराल" जो एक संपादक के लिए असहनीय है)। विम डॉक्स में अधिक देखने पर, मुझे एहसास हुआ कि मुझे वास्तव में प्लगइन्स की आवश्यकता नहीं थी। स्टॉक की कई विशेषताएं काफी अच्छी थीं, और, उन लोगों के लिए जो विम के पास नहीं थे, शेल जाने का रास्ता था। फाउंडेशनल रूप से (इसके अपवादों को अनदेखा करते हुए), यूनिक्स दर्शन के अनुसार, विम एक संपादक है जो अन्य ओएसिंग के साथ अच्छी तरह से अंतर करता है। मेरा मानना ​​है कि इसका सबसे अच्छा उपयोग करने का तरीका है। कोई प्लगइन्स नहीं।
JoL

2

यदि कॉलम ठीक से संरेखित हैं, तो यह एक साधारण ऑनलाइनर के साथ किया जा सकता है।

  1. पहले ब्लॉक-वार विजुअल मोड में कॉलम का चयन करें क्योंकि अन्य उत्तरों में डिस्प्ले है -> CTRL-V+ कर्सर को स्थानांतरित करें
  2. के साथ चयन yank y
  3. प्रकार: :echo eval(join(split(@", '\_s\+'), '+'))जो रिक्त स्थान और नई लाइनों पर लटके हुए पाठ को विभाजित करता है, तत्व के साथ तत्व को फिर से जोड़ता है +, और स्ट्रिंग का मूल्यांकन करता है।
  4. आगे बढ़ने का एक और तरीका: नईलाइन्स को बदलें +और मूल्यांकन करें: :echo eval(substitute(@", "\n", '+', 'g'))- eval()हमारे पास सबसे करीबी चीज reduceहै।

यदि नहीं, तो आपको फ़ील्ड्स की गणना करने के लिए अन्य ट्रिक्स का उपयोग करना होगा। उदाहरण के लिए, split(getline('.'), "[ \t|]\\+")आपके सरणी में एक पंक्ति से कॉलम को विभाजित करने के लिए उपयोग किया जा सकता है। वहाँ से, यह उतना ही सरल हो जाता है:

  1. विजुअल मोड में अपनी लाइनों का चयन करें
  2. :echo eval(join(map(getline("'<", "'>"), { -> split(v:val, "[ \t|]\\+")[2] }), '+'))

जादुई मूल्यों (क्षेत्र संख्या - 1, और +) से छुटकारा पाने के लिए , यह एक कमांड बन सकता है

:command! -range=% -nargs=+ OnField 
    \ echo { field, what -> eval(join(map(getline(<line1>, <line2>), { -> split(v:val, "[ \t|]\\+")[field-1] }), what))}(<f-args>)

जिसका उपयोग किया जा सकता है:

:OnField  3 +
:2,5OnField  3 +
:'<,'>Onfield 3 *   " after line-wise selection
....

नोट: यहाँ मैं Vim 7.4.1xxx से लैम्ब्डा का उपयोग करता हूँ


1

डेमियन कॉनवे द्वारा ++प्लगइन से वैंपvmath

  1. से प्लग-इन इंस्टॉल GitHub (केवल 178 SLOC) जैसे

    $ wget https://raw.githubusercontent.com/thoughtstream/Damian-Conway-s-Vim-Setup/master/plugin/vmath.vim -P ~/.vim/pack/manual/start/damians-tools/plugin
    
  2. अपने vimrc में मैपिंग जोड़ें

    vmap <silent><expr>  ++  VMATH_YankAndAnalyse()
    

    हालाँकि, मैं कुछ और, उदाहरण के लिए उपयोग करने का सुझाव दूंगा gA

  3. तीसरे 2f|कोलम में जाएं और दृश्य-ब्लॉक मोड में कॉलम का चयन करें<C-V>G$
  4. प्रेस ++(या अपने चुने हुए मानचित्रण)
  5. परिणाम दिखाए गए हैं और रजिस्टर में संग्रहीत किए गए हैं (योग में s)
  6. रजिस्टर से योग डालें s, जैसे"sp

इस प्लगइन की एक प्रस्तुति के लिए YouTube वीडियो डेमियन कॉनवे, "अधिक तुरन्त बेहतर विम" ​​- OSCON 2013 (29 मिनट से शुरू) देखें।


1

सीएसवीकैटcsvstat से बाहरी क्ली टूल

:!csvstat -d '|' -H -c 4 --sum %
69.5

विकल्पों की संक्षिप्त व्याख्या

  • -d DELIMITERइनपुट CSV फ़ाइल का परिसीमन वर्ण। यहाँ |
  • -H निर्दिष्ट करें कि इनपुट CSV फ़ाइल में कोई हेडर पंक्ति नहीं है।
  • -c COLUMNSएक अल्पविराम द्वारा स्तंभ सूचकांकों या नामों की सूची की जांच की जानी चाहिए। सभी स्तंभों के लिए डिफ़ॉल्ट।
  • --sum केवल आउटपुट बोता है।

यह उपकरण न्यूनतम, औसत, माध्य, stdev (मानक विचलन), अद्वितीय मान, बारंबार मूल्यों की सूची भी प्रदान करता है।

के साथ फाइल में डालें

<C-r>=system("csvstat -d '|' -H -c 4 --sum FILENAME 2> /dev/null")  

स्थापना

MacOS पर csvkit होमब्रेव और डेबियन / उबंटू के माध्यम से उपलब्ध है और इसी के साथ इसे स्थापित किया जा सकता है $ sudo apt install csvkit

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