Как соединить несколько линий по шаблону?

Как соединить несколько линий по шаблону?

Я хочу объединить несколько строк в файле на основе шаблона, который является общим для обеих строк.

Вот мой пример:

{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, но я понятия не имею, как это реализовать. Есть идеи?

/РЕДАКТИРОВАТЬ:

Я нашел «обходной путь»:

Сначала удалите все предыдущие символы «{1» из группы два в режиме ВИЗУАЛЬНОГО БЛОКА с помощью C-V(или аналогичной комбинации клавиш), затем отсортируйте все строки по номеру с помощью :%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

Вот как это можно сделать в оболочке с помощью файла:

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}становится { 101 }и {1101}становится {1 101 }). Затем он использует эти трехзначные числа как поле для joinкомандного ключа on. Последняя 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.}

Для нескольких шаблонов повторите с дополнительными командами, добавьте цикл или зациклите его из оболочки, например:

$ 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.}

Использовать только оболочку для анализа данных гораздо проще, например:

$ 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.}

Связанный контент