2

これは、この質問の拡張です(以前に尋ねました):

1行おきに削除し、選択後に削除した結果を貼り付ける方法は?

、しかし今、私はn-stripedデータに一般化したいと思います

したがって、この質問の拡張は、これをストライピングのないデータセットにどのように一般化するのでしょうか。

明らかに、上記は事実上1行おきに2行のデストライピングですが、以下のこのパターンのデータを3行のデストライピングに効果的にソートしたい場合はどうでしょうか。N列のデスストライプ?

前:

111
222
333
444
555
666

NEW AFTER(2ストライプを使用している場合):

111
333
555
222
444
666

NEW AFTER(3ストライプは以下のように再分類されます):

111
444
222
555
333
666

これにはアルゴリズム名があるかもしれません。私はソートの経験が豊富ではありませんが、その名前がある可能性があります。誰かが明確にできる場合は、私に知らせてください。

繰り返しになりますが、パラメーター付きのマクロ(またはそうでない)は、ここでの解決策のために私がやろうとしていることです。これは、ソートユーティリティスペースでも効果的かもしれませんが、前の質問への回答に基づいて、vimscriptで実行可能だと思います。

したがって、私がスクリプト用に作成するのは、次のようなものです(データに対して視覚的な行選択を行います)。次に、次のようなユーザーマクロ関数を呼び出します。

:'<','>' call Destripe(2)
:'<','>' call Destripe(3)

ここで、loneパラメーターはストライピングを記述します。

別の例(私がやろうとしていたことをより明確にするため)、3つのストライプのデータがある場合

前(LHS)と後(RHS):

aaa        aaa
bbb        aaa
ccc        aaa
aaa        bbb
bbb        bbb
ccc        bbb
aaa        ccc
bbb        ccc
ccc        ccc

2ストライプデータの例

前(LHS)と後(RHS):

aaa        aaa
bbb        aaa
aaa        aaa
bbb        bbb
aaa        bbb
bbb        bbb

アイデアをくれた@lornixに感謝します

4

3 に答える 3

2

正直なところ、これが頻繁に実行されるものでない場合、またはストライプが多すぎない場合は、コマンド ラインで次のように入力します (3 つのストライプの場合)。これを一般化する方法がわかるかもしれません。

:let @a = '' | let @b = ''
:g/^/ +d A | d B
:put a | put b
于 2012-07-12T11:03:40.597 に答える
2
"
function! Destripe(stripe) range
    call setpos('.',[0,a:firstline,1,0])
    let numlines=(a:lastline-a:firstline+1)/a:stripe
    let currentline=a:firstline+a:stripe-1
    while numlines > 0
        call setpos('.',[0,currentline,1,0])
        let currentline=currentline+a:stripe-1
        silent :.m$
        let numlines=numlines-1
    endwhile
endfunction
"
%call Destripe(2)

111,222,333...行のリストで上記をソースすると、次のようになります:(スペースを節約するために2倍にします)

111    111
222    333
333    555
444    777
555    999
666    222
777    444
888    666
999    888

ファイルの現在の(シフトされた)内容からの読み取り、またはファイルの元の内容からの読み取りを指定していないため、3以降では探しているものが生成されない可能性があります。(それは意味がありましたか?)

書かれているように、'%'、'<,'>、または行番号の範囲を指定する必要があります。

于 2012-07-10T11:14:53.547 に答える
0
function! Destripe(stripe) range

let s:rowbeg=getpos("'<")[1]           
let s:rowend=getpos("'>")[1]           
let s:curSetLngth=s:rowend-s:rowbeg+1

let stripe=a:stripe
let s:rowend += 1            

while stripe >= 2

  let stripeMin1 = stripe - 1                 

  " clear register
  let @e=''                                   

  " delete last stripe and append
  " to the e register
  execute "let @a='".stripeMin1."j\"Edd'"     

  " count how many times to perform a-macro
  let s:stripesInSlctn = s:curSetLngth / stripe           

  "silent ":'<" 
  let s:count=0
  while s:count <= s:stripesInSlctn
    norm @a 
    let s:count = s:count + 1
    "dbg echo s:count s:stripesInSlctn s:curSetLngth stripe s:rowbeg s:rowend
  endwhile

  let s:curSetLngth -= s:stripesInSlctn + 1

  " rowend location
  let s:rowend -= s:count      
  execute s:rowend

  " e-register collected the stripes
  " so place at bottom of selection
  norm "ep
  execute s:rowbeg
  let stripe -= 1
  let s:stripesInSlctn -= 1
endwhile

endfunction

これをきれいにする方法があれば教えてください。たとえば、スクリプトの設定方法が原因で、視覚的な線の選択でのみ機能します。

コマンドラインから呼び出すには、視覚的に行を選択してから

:'<,'> call Destripe(n)

ここで、n はストライプの数です。

効果的なスクリプトは、次の BEFORE (LHS) & AFTER (RHS) を実行します。

aaa        aaa
bbb        aaa
ccc        aaa
aaa
bbb        bbb
ccc        bbb
aaa        bbb
bbb 
ccc        ccc
           ccc
           ccc

ソリューションの潜在的な問題は、ストライプ化されていない結果の間に空白が常に存在することです。誰かがそれをデバッグする方法を知っていますか? ほとんどの場合、これで作業が完了します。インスピレーションをくれた@lornixに感謝します(vimでスクリプトを書く方法さえ知りませんでした!また、範囲を関数に与える方法も知りませんでした)。SO コミュニティの改善方法についてご意見がありましたら、よろしくお願いいたします。

もう 1 つの問題として、norm コマンドは、n 行単位ではなく「各行」単位で機能するため、単純に使用できないという事実があります。したがって、基本的には、ノルムが n 行ごとに動作する方法を望んでいました (ここにあるような乗算のシナリオ、または 3 行ごと、4 行ごとなどに関心がある場合に役立ちます) おそらく、次の機能があります。私はちょうど使用していない標準?

于 2012-07-11T15:27:54.473 に答える