vi / vimの巧妙な使用-数値の加算と減算、増分(回転)、シーケンスなど。
目次
1.機能的、デジタル加算および減算
置換コマンドs ///では、関数式を使用して置換コンテンツを書き込むことができます。形式は次のとおりです。
:s/替换字符串/\=函数式
関数式では、submatch(1)、submatch(2)などを使用して\ 1、\ 2などのコンテンツを参照でき、submatch(0)は一致のコンテンツ全体を参照できます。
例1:
:%s/\<id\>/\=line(".") " 将各行的 id 字符串替换为行号
:%s/^\<\w\+\>/\=(line(".")-10) .".". submatch(1) " 将每行开头的单词替换为 (行号-10).单词 的格式,
" 如第11行的 word 替换成 1. word
例2:次のマークダウンテキストで、章番号+1を追加する必要がある場合、
# 1. 指南
## 1.0 资源
...
## 1.1 架构
...
# 2. 实践
...
次の交換を実行します。
%s/#\+\s*\zs\d*\ze\./\=submatch(0)+1/
2.インクリメント。方法1
https://blog.easwy.com/archives/vim-tips-advanced-substitute-1/から転載
このトリックはVIMメーリングリストで見られ、非常に実用的です。
C言語プログラムの作成例を次に示します。完成させたいコードが次のとおりであると想定します。
#define BIT_MASK_1 (1 << 0)
#define BIT_MASK_2 (1 << 1)
#define BIT_MASK_3 (1 << 2)
#define BIT_MASK_4 (1 << 3)
#define BIT_MASK_5 (1 << 4)
#define BIT_MASK_6 (1 << 5)
#define BIT_MASK_7 (1 << 6)
#define BIT_MASK_8 (1 << 7)
#define BIT_MASK_9 (1 << 8)
#define BIT_MASK_10 (1 << 9)
#define BIT_MASK_11 (1 << 10)
#define BIT_MASK_12 (1 << 11)
#define BIT_MASK_13 (1 << 12)
#define BIT_MASK_14 (1 << 13)
#define BIT_MASK_15 (1 << 14)
#define BIT_MASK_16 (1 << 15)
#define BIT_MASK_17 (1 << 16)
#define BIT_MASK_18 (1 << 17)
#define BIT_MASK_19 (1 << 18)
#define BIT_MASK_20 (1 << 19)
#define BIT_MASK_21 (1 << 20)
#define BIT_MASK_22 (1 << 21)
#define BIT_MASK_23 (1 << 22)
#define BIT_MASK_24 (1 << 23)
#define BIT_MASK_25 (1 << 24)
#define BIT_MASK_26 (1 << 25)
#define BIT_MASK_27 (1 << 26)
#define BIT_MASK_28 (1 << 27)
#define BIT_MASK_29 (1 << 28)
#define BIT_MASK_30 (1 << 29)
#define BIT_MASK_31 (1 << 30)
#define BIT_MASK_32 (1 << 31)
次のように、行ごとに書き込む必要はありません。最初に最初の行を書き込むだけです。
#define BIT_MASK_1 (1 << 0)
次に、通常モードに戻り、この行に「Y31p」と入力し、この行をコピーして、31回貼り付けます。このようにして、上記のコンテンツの合計32行を取得します。
2.1コマンド
次に、「V31j」コマンドを使用してこれらの32行を選択してから、replaceコマンドを2回使用します。
:'<,'>s/BIT_MASK_\zs\d*\ze/\=line(".") - line("'<") + 1
:'<,'>s/\zs\d*\ze)$/\=line(".")-line("'<")
【或】
:%s/BIT_MASK_\zs\d*\ze/\=line(".") - line("'<") + 1
:%s/\zs\d*\ze)$/\=line(".")-line("'<")
このようにして、希望する結果が得られます。
この方法は、配列の添え字の自動追加やテキストの章の自動番号付けにも使用できます。規則的な式を使用して、自動的に番号を付ける番号を正確に見つけることができる限り、この方法を使用して自動的に番号を付けることができます。
2.2分析
2つのVIM置換コマンドを使用しました。以下でこれら2つのコマンドを詳細に分析してみましょう。
最初のコマンドを例にとると、2番目のコマンドは最初のコマンドと似ています。
:'<,'>s/BIT_MASK_\zs\d*\ze/\=line(".") - line("'<") + 1
このコマンドは、選択した領域を置換し、「BIT_MASK_」で始まり、その後に任意の数の数値が続く文字列を検索し、その数値に一致する位置を配置してから、これらの一致を次の式で計算された数値に置き換えます。数。
このコマンドの各要素の意味は次のとおりです。
'<,'> 我们所选中的区域 (:help '<,:help '> )
s 在选中的区域中进行替换 (:help :s )
\zs 指明匹配由此开始 (:help /\zs )
\d* 查找任意位数的数字 (:help /\d )
\ze 指明匹配到此为止 (:help /\ze )
\= 指明后面是一个表达式 (:help :s\= )
line(".") 当前光标所在行的行号 (:help line() )
line("'<") 我们所选区域中第一行的行号 (:help line() )
'<和'>是我们使用了"v","V"命令选中一个visual区域后,VIM设置的标记,分别用来标识visual区域的开始和结束。
「BIT_MASK_ \ zs \ d * \ ze」は、「BIT_MASK_」で始まり、その後に任意の数の数字が続く文字列を検索するために使用される正規表現です。このうち、「\ zs」と「\ ze」は、「BIT_MASK_0」の番号のみを置き換えるため、一致の開始位置と終了位置を指定するために使用されます。これは、検索時に一致領域のみが番号に配置されるためです。
置換操作では、異なる行の数値を異なる値に置き換える必要があるため、ここで式を使用して、置換された値を計算する必要があります。「?」コマンドの置換文字列が「=」で始まる場合、式計算の結果が置換に使用されることを示します。ここでの式は "line("。 ")-line(" '<")+ 1"です。ここで、 "line()"関数は行番号を取得するために使用され、現在の行の行番号を取得でき、指定されたマークの行番号。「Line( "。")」は、現在カーソルが配置されている行の行番号を取得するために使用され、「line( "'<")」は、「' <」マークが配置されている行の行番号を取得するために使用されます。これらの2つの行番号に1を加えたものの違いは、置き換えたい値です。
2.3Excelの3行目の単価の合計の例
-
たとえば、Execl形式のデマンドの列L = SUM(単価<単価> *数量<行N>)L4 = B4*B3+C4*C3+D4*D3+E4*E3+F4*F3+G4*G3+H4*H3+I4*I3+J4*J3+K4*K3
そして、列Lにはたくさんの行があります
-
問題
は最初の列のL4Excelテーブルを埋めますが、ドロップ塗りつぶし時間の方法を使用できません(L5はB5 * B4 + C5 * C4 + ...になります)。この問題は、上記の方法で解決できます。 -
ステップ1、vimを使用して、次のようにL番目の列とN行(たとえば、50行)をコピーして貼り付けます。
=B4*B3+C4*C3+D4*D3+E4*E3+F4*F3+G4*G3+H4*H3+I4*I3+J4*J3+K4*K3 ... =B4*B3+C4*C3+D4*D3+E4*E3+F4*F3+G4*G3+H4*H3+I4*I3+J4*J3+K4*K3
-
ステップ2、次のコマンドを数回実行します
%s/[^0123456789]\+\zs4\ze\*/\=line(".")+3/ # 或 %s/[A-Z]\+\zs4\ze\*/\=line(".")+3/
-
ステップ3、結果をコピーしてExcelに貼り付けると、完了です。
3.インクリメント:方法2
転載元:https://blog.easwy.com/archives/vim-tips-advanced-substitute-1/
同じ機能を実行する別の方法があります。
VIMの置換機能を使用して、効率的なコード記述を実現します。この記事では、同じ機能を実現するための別の方法を紹介します。
最初に例を見てみましょう。
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(0).text;
Children = lview.focusedItem.subItems.opIndex(0).text;
login = lview.focusedItem.subItems.opIndex(1).text;
txtCust.text = lview.focusedItem.subItems.opIndex(2).text;
txtProj.text = lview.focusedItem.subItems.opIndex(3).text;
txtbDate.text = lview.focusedItem.subItems.opIndex(4).text;
txtdDate.text = lview.focusedItem.subItems.opIndex(5).text;
txteDate.text = lview.focusedItem.subItems.opIndex(6).text;
txtPM.text = lview.focusedItem.subItems.opIndex(7).text;
txtLang.text = lview.focusedItem.subItems.opIndex(8).text;
txtVendor.text = lview.focusedItem.subItems.opIndex(9).text;
txtInvoice.text = lview.focusedItem.subItems.opIndex(10).text;
txtPMFund.text = lview.focusedItem.subItems.opIndex(11).text;
txtProjFund.text= lview.focusedItem.subItems.opIndex(12).text;
txtA_No.text = lview.focusedItem.subItems.opIndex(13).text;
txtNotes.text = lview.focusedItem.subItems.opIndex(14).text;
txtStatus.text = lview.focusedItem.subItems.opIndex(15).text;
上記のコードの括弧内の数字を、0から始まる連続した増加シーケンスに置き換える必要があります。次に例を示します。
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(1).text;
Children = lview.focusedItem.subItems.opIndex(2).text;
......
上記の要件を達成するには、上記の方法に加えて、次のコマンドを使用することもできます。
:let n=0 | g/opIndex(\zs\d\+/s//\=n/|let n+=1
このコマンドは、前の記事で紹介したコマンドと似ています。また、置換関数とVIMの式を使用します。違いは、現在の位置を計算するために「line()」関数を使用しないため、置換領域を事前に選択する必要がないことです。代わりに、変数を直接割り当てに使用してください。
このコマンドの要素の簡単な説明は次のとおりです。
let 为变量赋值 (:help let )
| 用来分隔不同的命令 (:help :bar )
g 在匹配后面模式的行中执行指定的ex命令 (:help :g )
\zs 指明匹配由此开始 (:help /\zs )
\d\+ 查找1个或多个数字 (:help /\d )
s 在选中的区域中进行替换 (:help :s )
\= 指明后面是一个表达式 (:help :s\= )
したがって、このコマンドの実行プロセスは次のとおりです。
给变量n赋值为0;
查找模式"opIndex(\zs\d\+",使用变量n的值替换匹配的模式字符串;
给变量n加1;
回第二步;
需要说明一下"|",它用来分隔不同的命令。
さらに、substituteコマンドで、一致するパターン文字列を省略すると、以前に定義された一致するパターン文字列が使用されます。この場合は、「global」コマンドで定義された「opIndex(\ zs \ d +」です。
上記の方法に加えて、数や日付などの増減を具体的に実装するVIMプラグインもあります。このプラグインは次のURLからダウンロードできます。
http://vim.sourceforge.net/scripts/script.php?script_id=670
或
http://mysite.verizon.net/astronaut/vim/index.html#VISINCR
4. 2つのヒント(単語数を数え、10進数を16進数に変換します)
さらに2つのヒントを紹介します。
これらの2つのテクニックは最近見られました、それらを忘れないようにそれらを記録してください。
4.1 [ヒント1]記事の単語数を数える
最初のものはVIMメーリングリストで見られ、記事の単語数を数える方法を提供しました。
完全なファイル内の単語数をカウントするには、Unixでwcツールを使用して、ファイル内の行、単語、および文字の数をカウントできます。
特定のパターンの発生回数だけをカウントしたい場合は、wcツールは無力です。現時点では、VIM置換機能を使用できます。
記事に表示される単語の数を数えたい場合は、次のコマンドを使用できます。
:%s/\w//gn
簡単に説明すると、このコマンドは実際にファイル全体に表示される単語の数を報告します。コマンドは次のように分類されます。
%s 在整个文件中替换 (:help :s )
\w 匹配一个字 (word) (:help /\w )
g 替换行内所有出现的匹配 (:help :s_flags)
n 只报告匹配的数目,并不真正进行替换(:help :s_flags)
LaTeXを使用して論文を書いている場合は、この方法でLaTeXの制御文字を除外し、論文の実際の単語数を数えることができます。この例は、参照ドキュメントにリストされている電子メールに記載されています。
VIMの「:helpcount-items」と「:helpcount-bytes」では、数値をカウントするその他の方法を確認できます。
4.2 [トリック2] 10進数の文字列を16進数に変換する
この手法は、Shuimu CommunityのVIMバージョン(http://www.newsmth.org/bbsdoc.php?board=VIM)で見られます。
この記事では、10進数の文字列を16進数に変換する方法について説明します。VIMを使用して変換を完了する最も簡単な方法は次のとおりです。
:%s/\d\+/\=printf("%X", submatch(0))/g
このコマンドの原理は、数字の文字列をprintf()関数の出力に置き換えることです。printf()関数の出力は、まさにこの数字の文字列の16進形式です。
内訳は以下のとおりです。
%s 在整个文件中替换 (:help :s )
\d\+ 匹配一个或多个数字 (:help /\d :help /\+ )
\= 使用表达式的结果进行替换 (:help /\w )
printf 按指定格式输出 (:help printf() )
submatch() 返回:s命令中的指定匹配字符串 (:help submatch() )
g 替换行内所有出现的匹配 (:help :s_flags)
看来,替换命令的巧妙使用可以完成很多意想不到的功能!
5.ナンバーシーケンス(レンジ機能)
場合によっては、次のような一連の番号を生成する必要があります。
5
6
7
...
100
vimでは、このシーケンスを生成する方法はたくさんありますが、そのうちの1つは次のとおりです。
:s/^/\=range(5, 100)
同様に、2のステップで一連の番号を生成できます。
:s/^/\=range(5, 100, 2)