Я хочу объединить несколько строк в файле на основе шаблона, который является общим для обеих строк.
Вот мой пример:
{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.}