1

Input

  • Every line is separated into 8 parts by semicolons
  • Every part can include words,numbers,space etc.

Output

I am trying to replace the space in the 6th part with a semicolon, thus separating the line again, making the total number of parts 9.

Example

1;30;68;Az LEMda;Ads Awdsâ;1 Bethesda, Galilea, Impe Mkals;29;63
264;16 October 1978;2 April 2005;AAz Jgfg adal II;Madwl Qózca Asdtyła;20 May 1920 Maklo, Polasn;58;84

would end up like

1;30;68;Az LEMda;Ads Awdsâ;1;Bethesda, Galilea, Impe Mkals;29;63
264;16 October 1978;2 April 2005;AAz Jgfg adal II;Madwl Qózca Asdtyła;20;May 1920 Maklo, Polasn;58;84

Attempts

I tried to find the space using anything ranging from regex to \zs but failed. The closest I came was finding the 5th semicolon.

%s/\(.\{-};\zs\)\{5}/;/g

But I need to find the space that comes after the number that comes after the 5th semicolon, so this kind of thinking got me nowhere and now I am trying to find the space in the parts that I defined earlier.

I could put awk into vim but then again I am fairly new with it. I managed to find the 6th part and change the space into a semicolon, but then it changes all the spaces, not just the first one.

:%! awk 'BEGIN{FS=OFS=";"} {gsub(/ /, ";", $6)} 1'

How can I just change the first space in the 6th part?

4
  • 1
    arthionne, welcome to Vi and Vim! I've edited your question to make it a bit clearer (note that ; is a semicolon). Just to clarify: you want to change only the 1st space after the 6th semicolon?
    – D. Ben Knoble
    Oct 29, 2019 at 1:03
  • 1
    Yes, that is correct. Also thank you for cleaning up my question and making it more readable.
    – arty
    Oct 29, 2019 at 1:04
  • Sorry, actually, after the 5th semi (the 6th part)?
    – D. Ben Knoble
    Oct 29, 2019 at 1:04
  • Yes, this one is correct.
    – arty
    Oct 29, 2019 at 1:05

2 Answers 2

4

substitute

I was able to do this with just

%s/\(.\{-\};\)\{5\}[^ ]*\zs /;/

(Aside: set hlsearch incsearch really helps here if you don't use them regularly. I basically did a /-search and tooled with the regex until it looked right—based on the highlighted feedback—and then did :%s//;/ to re-use my search as the substitute pattern.)

Breakdown

%s/\(.\{-\};\)\{5\}[^ ]*\zs /;/
  • % on the whole file
  • s substitute
    • \( the group
    • .\{-\} of any character (non-greedy)
    • ; followed by a semi
    • \) (end group)
    • \{5\} 5 times
    • [^ ]* followed by non-spaces
    • \zs start match here (this controls what will actually be replaced
    • a space
  • ; with a semi-colon

The power of macros

A macro based solution:

qq0f5;f r;q

Then, on each line you want to fix, @q. You can even use :%normal! @q to run it on the whole file, or :g/my_pattern/normal! @q to only run it on lines which match my_pattern.

Breakdown

  • q record macro
  • q into q register
  • 0 go to start of line
  • 5f; find the fifth semicolon
  • f find a space
  • r; replace it by a semicolon
  • q quit recording

(I actually prefer this solution, because it's vastly easier on the brain than the regex, and and it's easier to modify according to your needs. Plus, it simulates how I would fix one line normally.)

3
  • 1
    Thanks for the answer. What if I wanted to put the semicolon in the space that comes before the last word in the 6th part?
    – arty
    Oct 29, 2019 at 1:30
  • Probably %s/ \ze\(.\{-\};\)\{6\}/;/, but I'm not sure
    – D. Ben Knoble
    Oct 29, 2019 at 1:37
  • 1
    @arthionne I've added a macro-based solution, which is way easier to modify if you know the normal commands
    – D. Ben Knoble
    Oct 29, 2019 at 1:41
2

If you are using csv data, you can try my csv pluging.

In particular it provides a command SearchInColumn, that allows to search for a pattern in a specific column. If you want to replace the value then, simply use a :s command with an empty pattern (which will then re-use the last search pattern, which in this case then comes from the :SearchInColumn command).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.