如何根據模式連接多條線?

如何根據模式連接多條線?

我想根據兩行共享的模式將多行連接到一個檔案。

這是我的例子:

{101}{}{Apples}
{102}{}{Eggs}
{103}{}{Beans}
{104}...
...

{1101}{}{This is a fruit.}
{1102}{}{These things are oval.}
{1103}{}{You have to roast them.}
{1104}...
...

我想加入隊伍{101}{}{Apples}{1101}{}{This is a fruit.}

到一條生產線{101}{}{Apples}{1101}{}{This is a fruit.}進行進一步處理。

其他線路也是如此。

正如您所看到的,兩條線路共享數字 101,但我不知道如何實現這一點。有任何想法嗎?

/編輯:

我找到了一個「解決方法」:

C-V首先,使用(或類似的快捷方式)在 VISUAL BLOCK 模式下從第二組中刪除所有前面的“{1”字符,然後使用 來按編號對所有行進行排序:%sort n,然後使用 來連接每隔一行,:let @q = "Jj"然後使用來連接500@q

這有效,但給我留下了{101}{}{Apples} 101}{}{This is a fruit.}.然後我需要在每行中添加缺少的字元“{1”,這不完全是我想要的。任何幫助表示讚賞。

答案1

而不是刪除{1,只需執行

:%sort rn /\d\d\d}/

這將進行數字排序,但在每一行上它只會查看三位數字,後面跟著一個 }。

另外,為了之後加入隊伍,我會這麼做

:g/{\d\d\d}/j!

答案2

以下是在 shell 中使用檔案執行此操作的方法:

join -j 2 \
    <(sed -n '/^{...}/{s/{/{ /;s/}/ }/;p}' inputfile) \
    <(sed -n '/^{....}/{s/{./& /;s/}/ }/;p}' inputfile) |
    sed 's/^\([^ ]*\) { }{}\({[^}]*}\) {1 }\({.*}\)$/{\1}{}\2{1\1}\3/'

它使用前兩次呼叫sed根據第一組花括號之間的位數來分割文件,並在最後三位數字周圍添加空格({101}become{ 101 }{1101}becomes {1 101 })。然後它使用這些三位數作為join命令鍵的欄位。最後一個sed指令將數字放回原來的位置,並刪除先前新增的額外空格。

一位vim大師可能可以在內部做得更好vim。我可以使用 AWK 做一些比上面更簡單的事情。

答案3

以下是從命令列使用 Vim/Ex 編輯器處理一種模式的範例:

$ ex +'redir @a|sil g/101}/' +'redi>>/dev/stdout|echon join(split(@a),"")' -scq! input.txt 
{101}{}{Apples}{1101}{}{This is a fruit.}

對於多種模式,要么使用額外的命令重複,添加循環,要么從 shell 循環它,例如

$ for i in `seq 1 3`; do ex +"redir @a|sil g/10$i}/" +'redi>>/dev/stdout|echo join(split(@a),"")' -scq! input.txt; done
{101}{}{Apples}{1101}{}{Thisisafruit.}
{102}{}{Eggs}{1102}{}{Thesethingsareoval.}
{103}{}{Beans}{1103}{}{Youhavetoroastthem.}

僅使用 shell 來解析數據,就簡單多了,例如:

$ grep "101}" input.txt | xargs
{101}{}{Apples} {1101}{}{This is a fruit.}

對於多行:

$ for i in `seq 1 4`; do grep "10$i}" input.txt | xargs; done
{101}{}{Apples} {1101}{}{This is a fruit.}
{102}{}{Eggs} {1102}{}{These things are oval.}
{103}{}{Beans} {1103}{}{You have to roast them.}

相關內容