Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim - how to join lines using matching pattern

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?

like image 562
javaman717 Avatar asked Jan 22 '16 16:01

javaman717


People also ask

How do I join lines in Vim?

When you want to merge two lines into one, position the cursor anywhere on the first line, and press J to join the two lines. J joins the line the cursor is on with the line below. Repeat the last command ( J ) with the . to join the next line with the current line.

Which command joins next line to current line?

Joins consecutive lines. The J (join) command joins a specified number of lines together as one line. Number of consecutive lines, starting with the current line, to be joined to the current line.

How do you add a string at the end of each line in Vim?

On a character in the first line, press Ctrl-V (or Ctrl-Q if Ctrl-V is paste). Press jj to extend the visual block over three lines. Press $ to extend the visual block to the end of each line. Press A then space then type Hello world.

What is Vim stack overflow?

Quincy Larson. Vim is a popular keyboard-only code editor originally released in 1991. It is famously difficult to learn, but many developers swear by it. Vim is installed on pretty much every Linux- or Unix-based computer, and if you accidentally open it, it's quite difficult to exit.


1 Answers

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
like image 76
Ingo Karkat Avatar answered Dec 06 '22 16:12

Ingo Karkat