我想根據兩行共享的模式將多行連接到一個檔案。
這是我的例子:
{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.}