Bir sayı sütununun toplamını hızlı bir şekilde hesaplayın


15

Şuna benzeyen bir markdown tablosu yazıyorum:

| 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   |

Hızlı bir şekilde üçüncü sütunun toplamını hesaplamak ve arabelleğe eklemek için bir yol arıyorum. Aklımdaki çözüm, görsel blok modundan (tüm sayıları seçmek için) ve belki de ifade kaydından (matematik yapmak için) faydalanır.

Bu yerel Vim komutlarını kullanarak mümkün olabilir mi? Değilse, bana yardımcı olabilecek bir eklenti var mı?


1
Bu makaleye göz atabilirsiniz
nobe4

Yanıtlar:


15

Bir eklenti yazdım: görsel seçimi destekleyen ve matematik hesaplamaları yapan https://github.com/sk1418/HowMuch .

Eklenti varsayılan olarak üç matematik ifadesi değerlendirme motorunu destekler: Gnu bc, python ve vimscript. Hesaplamaları belirli bir hesap üzerinde yapabilir veya eklentinin sizin için otomatik olarak bir tane seçmesine izin verebilirsiniz.

Aşağıdaki gibi bir örnekle çalışır:

resim açıklamasını buraya girin

Ayrıntılar için lütfen github'daki README'yi okuyun.


Cevabınızı seçmek, toplamak ve eklemek için gerekli tuş vuruşlarını dahil etmeniz yararlı olacaktır.
pdoherty926

@ pdoherty926 For details please read the README on github.Bu sorun için bastığım tuş vuruşlarını buraya koyarsam bile, ne kadar yardımcı olabileceğini görmüyorum, sadece 3 veya 4 tuş kombinasyonu. Eğer senaryom gerçekten birisi tarafından isteniyorsa, detayları yine de kontrol edecektir.
Kent

12

Eklentileri kullanmak veya bir bash betiğine bırakmak istemiyorsanız, aşağıdakine benzer bir şey yapabilirsiniz:

  • c-V {motions} "ay sütunu içine kopyala "a
  • :let @a = substitute(@a, 'c-V c-J', '+', 'g') sütun satırlarını +
  • ic-R=c-Radeğiştirileni "aifade yazmacından çalıştır

Alternatif olarak: İfade geçmişi girişini başka sütun toplamları için tekrar kullanılabilir hale getirme

  • ctrl-V {motions} y sütunu yank kaydına koy ""
  • ictrl-R=eval(substitute(@", '\n', '+', 'g'))

Başka bir sütun için tekrarlama:

  • ctrl-V {motion} y (Değişiklik yok)
  • ictrl-R=<CR>veya ifade kaydında başka bir şey yaptıysanız, yukarı ok tuşuyla (veya ctrl-Pyeniden eşlediyseniz) geçmişte dolaşın:
    ictrl-R=<up>...<up><CR>

1
Nedense ben sadece çift tırnak ile çözüm kullanmaya başardı "yerine tek tırnak 'üzerine substitutekomuta. Bunun bir nedeni olup olmadığını biliyor musunuz?
vappolinario

@vappolinario benim için her iki yönde de çalışıyor, bu yüzden korkarım bilmiyorum, üzgünüm.
Hovercouch

@Hovercouch Üçüncü adımda ayrıntıya girebilir misiniz? Tam olarak, yerine nasıl ifade yazmacından geçilir?
pdoherty926

Bir harita yapmaya ne dersiniz: `nnoremap <cs>: s / $ / \ = eval (yedek (@ 0, '[^ 0-9]', '+', 'g')) / <cr>`
SergioAraujo

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

Açıklama:

: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

Burada çalışan bir işlevi deniyorum:

" 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>

Yukarıdaki haritayı kullanarak, işlevi yükledikten sonra yapmanız gereken tek şey toplamak istediğiniz sayıları seçmek <leader>sve seçilen alanı toplamak için kullanmaktır .

İşlev açıklaması:

try/finally/endtryHataları yakalamak için ekstrüzyon kullanır .

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

Bu işlevi denemek istiyorsanız, aşağıdakileri yapın: Bu işlevi tarayıcınıza kopyalayın ve bu komutu vim'de çalıştırın, bu normal :@+ olarak kullanmanıza izin verecektir :call SumVis().

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

ctrl+ vİle görsel bir blok seçimi yapmanız gerekir, seçimi kaldırın ve son olarak işlevi çağırın. Veya hesaplamadan önce seçimi kendiliğinden kaldıran önerilen haritayı kullanabilirsiniz.



5

Vimscript'te bir eklenti yapmak veya kodlamak biraz ağır görünüyor. Eklentisiz bir vime ve harici araçlarla iyi bir kompozisyona inanıyorum.

Burada, arabellek kaydedilmemiş olsa bile çalışan user2571881'sine dayanan 1 seferlik bir komut verilmiştir.

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

Bu komutu ileride kullanmak üzere kaydetmek istiyorsanız, onu adlandırmak isteyebilirsiniz:

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

Görsel seçim ile çalışır. Birkaç satır seçer ve komut moduna girerseniz, vim :'<,'>, görsel seçim için satır aralığı olan komutunuza önek ekler . Böylece koşabilirsiniz:

:'<,'>SumColumn 3

seçili satırların yalnızca 3. sütununu toplar. Varsayılan olarak aralığıdır %yüzden,

:SumColumn 3

tüm satırların 3. sütununu toplar.

DÜZENLEME: Diğer alan ayırıcılarını belirtmek ve sonuncuya kadar sayılan sütunu varsayılan olarak kullanmak istiyorsanız, komutu içine alabilir bashve bağımsız değişkenleri bununla işleyebilirsiniz:

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

Şimdi,

:SumColumn

tablonun son sütununu "|" ile sayar alan ayırıcılar,

:SumColumn 3

tablonun 3. sütununu "|" ile sayar alan ayırıcılar ve

:SumColumn 3 +

"+" alan ayırıcıları olan bir tablonun 3. sütununu sayar.


Bir kişi diğer olası alan ayırıcılarıyla nasıl başa çıkabilir? Sadece çözümü daha genel hale getirmek için.
SergioAraujo

@ user2571881, cevabı düzenledim, bunu gösterdim.
JoL

@JoL vimrc gibi işlevler eklemek, vimrc'nizde SumColumn'eklentileriniz' olduğu anlamına gelir. Umarım, bunu zamanla sürdürmekte iyisinizdir. Benim için eklentiler, başkalarının yaratıcılığından yararlanarak, anlamlı parçalara ayrılma, dokümantasyon sağlar. Kimsenin hepsini tek başına (tpope hariç) oluşturmak için zamanı olmayan şaşırtıcı eklentileri geliştiren yukarı akışa katkıda bulunuyorum. Vim-surround, vim-kaçak, vim-kolay hizalama / vim-aslan, vim-engelsiz, vim-yorum, ultisnip veya vim-go, vim-rails, vimtex gibi ft'e özgü olanları kullanmıyor musunuz?
Hotschke

@Hotschke Buraya geldiğimde, soruyu gördüm ve "iyi, sadece awk ile boru" diye düşündüm. Ama sonra, kabul edilen cevabın "hey, bu yüzlerce LOC eklentisini indirin ve kurun" olduğunu gördüm. Üçüncü cevap, "hey, bu binlerce LOC eklentisini indirin ve yükleyin." Aşırı ve şişkin. Hayatınızda bir kereden fazla sütunları toplamanız gerekse bile, aşırıya kaçmış. Cevabım, bunu tek bir eklenti olmadan, sadece bir kez yapmanız gerekiyorsa saçma olmayan komutla nasıl yapabileceğinizi ve bunu yapmanız gerekirse parametrelerle basit bir komutu nasıl yapabileceğinizi göstermek içindir. sıklıkla.
JoL

@Hotschke Sorunuzu cevaplamak için, uzaktan serin görünen güneşin altındaki her eklentiyi yüklerdim, ama sonra vim inanılmaz derecede yavaştı (bir editör için dayanılmaz olan "biraz laggy" yi okuyun). Vim belgelerine daha fazla baktığımda, gerçekten eklentilere ihtiyacım olmadığını fark ettim. Stok özelliklerinin çoğu yeterince iyiydi ve vim'e sahip olmayanlar için kabuk gitmek için bir yoldu. Temel olarak (yapılan istisnaları göz ardı ederek), Unix felsefesine göre, vim diğer işletim sistemi araçlarıyla iyi bir şekilde birlikte çalışan bir editördür. En iyi şekilde kullanmanın yolu bu. O zamandan beri eklenti yok.
JoL

2

Sütunlar doğru şekilde hizalanmışsa, bu basit bir oneliner ile yapılabilir.

  1. diğer cevapların gösterdiği gibi ilk önce sütunu blok olarak görsel modda seçin -> CTRL-V+ imleci hareket ettirin
  2. seçimi y
  3. type: :echo eval(join(split(@", '\_s\+'), '+'))boşluklara ve yeni satırlara ayrılmış metni böler, öğeyi +karakterle yeniden birleştirir ve dizeyi değerlendirir.
  4. ilerlemenin başka bir yolu: yeni satırları değiştirmek +ve değerlendirmek: :echo eval(substitute(@", "\n", '+', 'g'))- sahip olduğumuz eval()en yakın şeydir reduce.

Değilse, alanları saymak için başka numaralar kullanmanız gerekir. Örneğin split(getline('.'), "[ \t|]\\+"), sütunları dizinizdeki bir satırdan ayırmak için kullanılabilir. Oradan, bu kadar basit hale gelir:

  1. görsel modda satırlarınızı seçin
  2. :echo eval(join(map(getline("'<", "'>"), { -> split(v:val, "[ \t|]\\+")[2] }), '+'))

Büyülü değerlerden (alan numarası - 1 ve +) kurtulmak için bir komut olabilir

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

Hangi ile kullanılabilir:

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

Not: Burada Vim 7.4.1xxx'ten lambdas kullanıyorum


1

++Plugin vmathDamian Conway tarafından vmap

  1. Dan eklenti yükleme github (sadece 178 sloc) örn

    $ 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'nize eşleme ekleyin

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

    Ancak, başka bir şey kullanmanızı öneririm, ör. gA

  3. Üçüncü 2f|sütuna git ve görsel blok modunda sütunu seç<C-V>G$
  4. Basın ++(veya seçtiğiniz eşleme)
  5. Sonuçlar kayıtlarda gösterilir ve saklanır (toplamı s)
  6. Kayıttan toplam ekle s, örn."sp

Bu eklentinin sunumu için "Daha Anında Daha İyi Vim" - OSCON 2013 (29. dakikada başlayan) YouTube videosu Damian Conway'e bakın .


1

Dış cli aracı csvstatdan csvkit

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

Seçeneklerin kısa açıklaması

  • -d DELIMITERGirilen CSV dosyasının karakteri sınırlanıyor. İşte |.
  • -H Girilen CSV dosyasında başlık satırı bulunmadığını belirtin.
  • -c COLUMNSİncelenecek sütun indekslerinin veya adlarının virgülle ayrılmış listesi. Varsayılan olarak tüm sütunlar.
  • --sum Yalnızca çıktı toplamları.

Bu araç ayrıca min, maks, ortalama, medyan, stdev (standart sapma), benzersiz değerleri sayma, sık değerler listesi sağlar.

İle dosyaya ekle

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

Kurulum

MacOS csvkit üzerinde homebrew ve Debian / Ubuntu ve benzeri üzerinden kurulabilir $ sudo apt install csvkit.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.