숫자 열의 총계를 빠르게 계산


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   |

세 번째 열의 총계를 빠르게 계산하고 버퍼에 삽입하는 방법을 찾고 있습니다. 내가 생각한 해결책은 비주얼 블록 모드 (모든 숫자를 선택하기 위해)와 어쩌면 표현식 레지스터 (수학을하기 위해)를 사용합니다.

기본 Vim 명령을 사용하여 가능합니까? 그렇지 않다면 나를 도울 수있는 플러그인이 있습니까?


1
이 기사를 볼 수 있습니다 : vim.wikia.com/wiki/Using_vim_as_calculator
nobe4

답변:


15

시각적 선택을 지원하고 수학 계산을 수행 하는 플러그인 https://github.com/sk1418/HowMuch 를 작성했습니다 .

플러그인은 기본적으로 Gnu bc, python 및 vimscript의 세 가지 수학 식 평가 엔진을 지원합니다. 특정 계산을 수행하거나 플러그인이 자동으로 계산하도록 할 수 있습니다.

다음과 같이 예제와 함께 작동합니다.

여기에 이미지 설명을 입력하십시오

자세한 내용은 github의 README를 읽으십시오.


답을 선택, 합계 및 삽입하는 데 필요한 키 입력을 포함하면 도움이됩니다.
pdoherty926

@ pdoherty926 내가이 For details please read the README on github.문제를 위해 눌렀 던 키 스트로크를 여기에 넣었더라도 그것이 얼마나 도움이되는지 보지 못하고, 그것은 단지 3 개 또는 4 개의 키 조합입니다. 누군가 내 스크립트가 실제로 필요한 경우 어쨌든 세부 사항을 확인합니다.
Kent

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
vappolinario

@ vappolinario 그것은 나를 위해 두 가지 방식으로 작동하므로 알 수 없습니다, 미안합니다.
Hovercouch

@Hovercouch 세 번째 단계를 자세히 설명해 주시겠습니까? 식 레지스터를 통해 대체를 실행하는 방법은 무엇입니까?
pdoherty926

지도를 만드는 방법 :`nnoremap <cs> : s / $ / \ = eval (substitute (@ 0, '[^ 0-9]', '+', 'g')) / <cr>`
SergioAraujo

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로 이것을 코딩하는 것은 약간 무겁습니다. 나는 플러그인이없는 vim과 외부 도구가있는 좋은 구성을 믿습니다.

다음은 user2571881을 기반으로하는 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

선택한 행의 세 번째 열만 합산합니다. 기본적으로 범위는입니다 %.

:SumColumn 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 +

"+"필드 구분 기호로 테이블의 세 번째 열을 계산합니다.


다른 가능한 필드 구분 기호를 어떻게 다룰 수 있습니까? 솔루션을보다 일반적으로 만들기 위해.
SergioAraujo

@ user2571881, 답변을 편집하여 표시했습니다.
JoL

@JoL SumColumnvimrc 와 같은 기능을 추가 하면 단순히 vimrc에 '플러그인'이 있습니다. 바라건대, 시간이 지남에 따라 이것을 잘 유지하십시오. 나를 위해 플러그인은 다른 사람들의 독창성을 활용하여 의미있는 부분으로 분리 된 문서화를 제공합니다. 나는 업스트림에 기여하여 아무도 스스로 플러그인을 만들 시간이없는 놀라운 플러그인을 향상시킵니다 (tpope 제외). vim-goround, vim-rails, vimtex와 같은 vim-surround, vim-fugitive, vim-easy-align / vim-lion, vim-unimpaired, vim-commentary, ultisnips 또는 ft-specifics를 사용하지 않습니까?
Hotschke

@Hotschke 여기에 왔을 때 나는 질문을 보았습니다. "좋아요. 그러나 그 대답은 "이 수백 개의 LOC 플러그인을 다운로드하여 설치하십시오"라는 대답을 보았습니다. 세 번째 대답은 "이 수천 개의 LOC 플러그인을 다운로드하여 설치하십시오."였습니다. 과잉이고 부풀어 오른다. 인생에서 열을 두 번 이상 합계해야하더라도 과잉입니다. 내 대답은이 작업을 한 번만 수행하면 단일 플러그인이 아닌 넌센스 명령 으로이 작업을 수행하는 방법 과이 작업을 수행 해야하는 경우 매개 변수를 사용하여 간단한 명령을 만드는 방법을 보여주기위한 것입니다. 자주.
JoL

@Hotschke 귀하의 질문에 대답하기 위해 원격으로 멋지게 보이는 태양 아래 모든 플러그인을 설치했지만 내 vim은 매우 느 렸습니다 (편집기가 견딜 수없는 "약간 게으른"읽기). vim 문서를 자세히 살펴보면 플러그인이 실제로 필요하지 않다는 것을 깨달았습니다. 많은 스톡 기능이 충분했고, vim이없는 기능은 쉘이 갈 길이었습니다. Unix 철학에 따라 vim은 기본적으로 (예외는 무시하고) 다른 OS 툴링과 잘 연동되는 편집기입니다. 그것이 최선의 방법이라고 생각합니다. 이후 플러그인이 없습니다.
JoL

2

컬럼이 올바르게 정렬되면 간단한 oneliner를 사용하여 수행 할 수 있습니다.

  1. 다른 답변에서 보여 주듯이 먼저 블록 방식의 시각적 모드 에서 열을 선택하십시오 -> CTRL-V+ 커서 이동
  2. 선택을 k 다 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

Damian Conway의 ++플러그인에서 vmapvmath

  1. github 에서 플러그인 설치 (178 슬롯 만)

    $ 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 비디오 Damian Conway, "More Instantly Better Vim"-OSCON 2013 (29 분에 시작)을 참조하십시오.


1

외부 CLI 도구 csvstat에서 csvkit

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

옵션에 대한 간단한 설명

  • -d DELIMITER입력 CSV 파일의 구분 문자입니다. 이곳까지 |.
  • -H 입력 CSV 파일에 헤더 행이 없도록 지정하십시오.
  • -c COLUMNS검사 할 쉼표로 구분 된 열 인덱스 또는 이름 목록. 모든 열이 기본값입니다.
  • --sum 출력 합계 만.

이 도구는 최소값, 최대 값, 평균값, 중앙값, 표준 편차 (표준 편차), 고유 값 수, 빈번한 값 목록을 제공합니다.

파일에 삽입

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

설치

macOS csvkit 은 homebrew 및 Debian / Ubuntu를 통해 사용할 수 있으며 이와 유사하게 설치 될 수 있습니다 $ sudo apt install csvkit.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.