LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-22-2017, 11:08 PM   #1
ufmale
Member
 
Registered: Feb 2007
Posts: 386

Rep: Reputation: 30
Change nth occurence in every line


I am trying to change every 4th occurence of "," in every line to ":" using vi. Anyone can suggest a solution. I search through the Internet, but couldn't find the right answer.
 
Old 10-22-2017, 11:23 PM   #2
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 5,511
Blog Entries: 3

Rep: Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773Reputation: 2773
Your pattern would be in the form of

Code:
%s/old/new/
with a lot of parenthesis.
 
Old 10-22-2017, 11:35 PM   #3
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 19,577

Rep: Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504
Use sed.
 
Old 10-25-2017, 10:08 AM   #4
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 756

Rep: Reputation: 144Reputation: 144
More specifically, something like this:
Code:
sed 's/^\([^,]*,[^,]*,[^,]*,[^,]*\),\(.*\)$/\1:\2/' infile.txt > outfile.txt
or
Code:
sed -i 's/^\([^,]*,[^,]*,[^,]*,[^,]*\),\(.*\)$/\1:\2/' inoutfile.txt
  • [^,] matches any character but a comma.
  • \1 matches the contents of the first parentheses.
 
Old 10-25-2017, 10:30 AM   #5
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 1,675

Rep: Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755
Indeed a brain teaser.
One comma that can be followed by some non-comma stuff, repeat 3 times (i.e. enclose in \( \) followed by \{3\}), and finally the comma that needs to be substituted.
What matches but needs to be kept is captured in another \( \) that is put back with \1
All that to be repeated until the end of the line.
Code:
sed -i 's/\(\(,[^,]*\)\{3\}\),/\1:/g' file
and in vi/vim
Code:
:%s/\(\(,[^,]*\)\{3\}\),/\1:/g
 
1 members found this post helpful.
Old 10-25-2017, 10:51 AM   #6
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 756

Rep: Reputation: 144Reputation: 144
Ah! "every" 4th occurrence. I missed that word. Very good, MadeInGermany.
 
Old 10-25-2017, 11:27 AM   #7
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,814

Rep: Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639
Quote:
Originally Posted by ufmale View Post
I am trying to change every 4th occurence of "," in every line to ":" using vi. Anyone can suggest a solution. I search through the Internet, but couldn't find the right answer.
Do a Google search on ...
replace every nth occurrence
... and find this ...
https://arstechnica.com/civis/viewtopic.php?t=370486
... which contains this ...
sed -e's/\(\([^;]*;\)\{8\}[^;]*\);/\1\n/g' nth.txt

Daniel B. Martin

Last edited by danielbmartin; 10-25-2017 at 11:42 AM.
 
Old 10-25-2017, 02:12 PM   #8
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 1,675

Rep: Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755Reputation: 755
This solution works as well, but can be optimized.
The -e option does not do anything because sed's first argument is always a script.
The very first [^;]* does not contribute and denotes a trailing [^;]*
It is more efficient to start with the ;
Code:
sed 's/\(\(;[^;]*\)\{8\}\);/\1\n/g' nth.txt
And now it is quite like my solution.
 
Old 10-25-2017, 02:31 PM   #9
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,814

Rep: Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639
Quote:
Originally Posted by MadeInGermany View Post
...And now it is quite like my solution.
Yes. Post #7 was not intended as a criticism or correction of your excellent solution. The purpose was to show the OP that a Google search led to a workable solution.

Daniel B. Martin
 
Old 10-25-2017, 05:10 PM   #10
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 19,577

Rep: Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504
Code:
sed 's/,/;/4' some.file
Simple is good.
 
2 members found this post helpful.
Old 10-25-2017, 07:15 PM   #11
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 756

Rep: Reputation: 144Reputation: 144
Quote:
Originally Posted by syg00 View Post
Code:
sed 's/,/;/4' some.file
Cool! I use sed a lot, but I didn't know about the number flag. Though I think that will only change the fourth comma, not every fourth comma.
 
Old 10-25-2017, 07:20 PM   #12
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 19,577

Rep: Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504Reputation: 3504
True - that nuance in the requirements evaded me. I shall retreat under my rock.
 
Old 10-25-2017, 07:25 PM   #13
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,814

Rep: Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639
Quote:
Originally Posted by syg00 View Post
Simple is good.
Simple is good but this solution fails for strings with 8 or more commas. See post #6.

Daniel B. Martin
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
replacing nth line of a file with a new line containing different sets of values kbashyal Linux - Newbie 8 10-08-2017 01:24 PM
Deleting a line with Nth occurence of anything. Eros He Linux - Newbie 10 09-30-2017 11:10 AM
[SOLVED] grep for pattern following the nth occurence of a character in a file cosminel Linux - Newbie 24 10-08-2013 02:34 AM
print lines form nth line to mth line which fulfill specific condition cristalp Programming 4 11-07-2011 07:39 AM
print nth line after the line which matches the string cristalp Programming 7 10-27-2011 01:53 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:06 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration