4

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

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

{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" из второй группы в режиме VISUAL BLOCK с помощью C-V (или аналогичного ярлыка), затем отсортируйте все строки по номерам с помощью :%sort n , затем присоедините каждую вторую строку с помощью :let @q = "Jj" сопровождается 500@q .

Это работает, но оставляет меня с {101}{}{Apples} 101}{}{This is a fruit.} . Затем мне нужно добавить пропущенные символы "{1" в каждой строке, не совсем то, что я хочу. Любая помощь приветствуется.

3 ответа3

3

Вместо удаления {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 клавиши команды соединения . Последняя команда sed возвращает цифры обратно на место и удаляет лишние пробелы, добавленные ранее.

Гуру vim вероятно, может сделать что-то лучше в vim . Я мог бы сделать что-то более простое, чем выше, используя AWK.

0

Вот пример использования редактора 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.}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .