Vim - how to join lines using matching pattern
Asked Answered
C

2

7

I have a txt file that contains contact info for businesses. Currently, each line contains a different piece of data for the business. I'm attempting to construct a pipe-delimited file with all the info for each business on a single line. The catch is that there are a different number of lines for each business. So the file looks like this:

Awesome Company Inc|
Joe Smith, Owner|
Jack Smith, Manager|
Phone: (555)456-2349|
Fax: (555)456-9304|
Website: www.awesomecompanyinc.com [HYPERLINK: http://www.awesomecompanyinc.com]|
  * Really Cool Company|
  * Line of business: Awesomesauce|
Killer Products LLC|
Jack Black, Prop|
Phone: (555)234-4321|
Fax: (555)912-1234|
1234 Killer Street, 1st Floor|
Houston, TX 77081|
  * Apparel for the classy assassin|
  * Fearful Sunglasses|
  * Member of the National Guild of Killers since 2001|
  * Line of business: Fuhgettaboutit|

etc.

So I can use :g/<pattern>/j to join lines within a pattern but I'm having trouble working out what the pattern should be. In the example above, lines 1-9 need to joined, and then lines 10-19.

The key is the lines that begin with 2 spaces and an asterisk:

  * Line of business

The pattern should basically say: "Starting with the first line beginning with a letter, join all lines until the first line after the last line beginning with \ \ \*\, then repeat until the end of the file."

How would I write this? Should I maybe do it in two steps - i.e., is there a way to first join all the lines starting with letters, then all the lines starting with \ \ \*\, then join each resulting pair?

Casino answered 22/1, 2016 at 16:32 Comment(0)
A
12

Starting with the first line beginning with a letter, join all lines until the first line after the last line beginning with \ \ *\, then repeat until the end of the file.

You can actually translate that almost literally to Vimscript:

  • Starting with the first line beginning with a letter is /^\a/
  • until the first line after the last line beginning with * is /^ \* .*\n\a: find a line starting with the bullet (^ \*), match the rest of the line (.*), and assert that the next line isn't a bulleted one (\n\a)
  • then repeat until the end of the file. is done via :global

Taken together:

:global/^\a/,/^  \* .*\n\a/join
Ailina answered 22/1, 2016 at 17:29 Comment(0)
A
0

Edit: nevermind, just realized that there are a bunch of settings that would have to be set for my solution to work. To make it work generally you would need

  for i in range(10)
      try
           v/business/join
      endtry
   endfor

And even that assumes that there isn't a business block that has more than 1024 lines. At that point you might as well use ranges

Alidia answered 23/1, 2016 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.