숫자 열의 총계를 빠르게 계산 테이블을 작성하고 있습니다. | 13/05/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 명령을 사용하여 가능합니까? 그렇지 않다면 나를 도울 수있는 플러그인이 있습니까?



답변

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

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

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

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

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


답변

플러그인을 사용하지 않거나 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>

답변

: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해제하고 마지막으로 함수를 호출해야합니다. 또는 계산하기 전에 선택 항목을 자체적으로 제거하는 제안 된 맵을 사용할 수 있습니다.


답변

csv 플러그인 이 이것을 허용합니다. :SumCol명령을 사용하고 설명서를 읽으십시오.


답변

플러그인을 만들거나 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 +

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


답변

컬럼이 올바르게 정렬되면 간단한 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의 람다를 사용합니다.


답변

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 분에 시작)을 참조하십시오.