How to skip replacing first occurrence of a character in each line? [duplicate]sed: delete all occurrences of a string except the first oneCheck for, and add, missing timestamps to individual lines in a fileReplace a word after a significant line and white spaces (inline) using sed?Replace data at specific positions in txt file using data from another fileHow do I replace the last occurrence of a character in a string using sed?Compare 1st Column in 2 Files and Replace 3rd Column of File 1 with 4th Column of File 2How to search between the 2nd and 3rd delimitersDeleting lines by matching 3rd and 4th character onlyReplace second occurence between colon and bracketHow to replace last occurrence of pattern in a third last line of a fileWant to replace the value of 4th column of data2.csv with the 4th column of other csv file data1.csv where 3rd and 4th column are same in both files

Who enforces MPAA rating adherence?

Print lines between start & end pattern, but if end pattern does not exist, don't print

Getting UPS Power from One Room to Another

New pedal fell off maybe 50 miles after installation. Should I replace the entire crank, just the arm, or repair the thread?

Thread Pool C++ Implementation

Which languages would be most useful in Europe at the end of the 19th century?

What is the maximum number of net attacks that one can make in a round?

How to decline a wedding invitation from a friend I haven't seen in years?

How can I search for all contacts without email?

Second (easy access) account in case my bank screws up

Is it possible for a vehicle to be manufactured without a catalytic converter?

How did old MS-DOS games utilize various graphic cards?

US doctor working in Tripoli wants me to open online account

Why does the Mishnah use the terms poor person and homeowner when discussing carrying on Shabbat?

Should I ask for an extra raise?

Determining fair price for profitable mobile app business

Are polynomials with the same roots identical?

Active low-pass filters --- good to what frequencies?

What is inside of the 200 star chest?

Why was this person allowed to become Grand Maester?

Wooden cooking layout

Has there been a multiethnic Star Trek character?

Why can I traceroute to this IP address, but not ping?

Bb13b9 confusion



How to skip replacing first occurrence of a character in each line? [duplicate]


sed: delete all occurrences of a string except the first oneCheck for, and add, missing timestamps to individual lines in a fileReplace a word after a significant line and white spaces (inline) using sed?Replace data at specific positions in txt file using data from another fileHow do I replace the last occurrence of a character in a string using sed?Compare 1st Column in 2 Files and Replace 3rd Column of File 1 with 4th Column of File 2How to search between the 2nd and 3rd delimitersDeleting lines by matching 3rd and 4th character onlyReplace second occurence between colon and bracketHow to replace last occurrence of pattern in a third last line of a fileWant to replace the value of 4th column of data2.csv with the 4th column of other csv file data1.csv where 3rd and 4th column are same in both files






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








10
















This question already has an answer here:



  • sed: delete all occurrences of a string except the first one

    4 answers



I have some files in the format



Y15-SUB-B04-P17-BK_M02734_4_000000000-ANNUF_1_1111_24724_4878;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1111_20624_14973;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1103_11326_10379;size=1;


I wish to replace every occurrence of the underscore (_) with a colon (:) EXCEPT for the first one. I want an output like this:



Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


I know I can use sed -i '' 's/_/:/g' old_file to replace ALL (or sed 's/_/:/g' old_file > new_file), and that I could add numbers to replace only the 2nd, 4th or so occurrence:



sed 's/_/:/2' old_file > new_file


But how to replace every occurrence on each line BUT the first?










share|improve this question















marked as duplicate by αғsнιη, terdon sed
Users with the  sed badge can single-handedly close sed questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
12 hours ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


















  • Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

    – 0xSheepdog
    May 31 at 18:20






  • 1





    Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

    – Christoffer Bugge Harder
    May 31 at 18:27






  • 4





    Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

    – 0xSheepdog
    May 31 at 18:31


















10
















This question already has an answer here:



  • sed: delete all occurrences of a string except the first one

    4 answers



I have some files in the format



Y15-SUB-B04-P17-BK_M02734_4_000000000-ANNUF_1_1111_24724_4878;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1111_20624_14973;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1103_11326_10379;size=1;


I wish to replace every occurrence of the underscore (_) with a colon (:) EXCEPT for the first one. I want an output like this:



Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


I know I can use sed -i '' 's/_/:/g' old_file to replace ALL (or sed 's/_/:/g' old_file > new_file), and that I could add numbers to replace only the 2nd, 4th or so occurrence:



sed 's/_/:/2' old_file > new_file


But how to replace every occurrence on each line BUT the first?










share|improve this question















marked as duplicate by αғsнιη, terdon sed
Users with the  sed badge can single-handedly close sed questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
12 hours ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


















  • Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

    – 0xSheepdog
    May 31 at 18:20






  • 1





    Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

    – Christoffer Bugge Harder
    May 31 at 18:27






  • 4





    Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

    – 0xSheepdog
    May 31 at 18:31














10












10








10


2







This question already has an answer here:



  • sed: delete all occurrences of a string except the first one

    4 answers



I have some files in the format



Y15-SUB-B04-P17-BK_M02734_4_000000000-ANNUF_1_1111_24724_4878;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1111_20624_14973;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1103_11326_10379;size=1;


I wish to replace every occurrence of the underscore (_) with a colon (:) EXCEPT for the first one. I want an output like this:



Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


I know I can use sed -i '' 's/_/:/g' old_file to replace ALL (or sed 's/_/:/g' old_file > new_file), and that I could add numbers to replace only the 2nd, 4th or so occurrence:



sed 's/_/:/2' old_file > new_file


But how to replace every occurrence on each line BUT the first?










share|improve this question

















This question already has an answer here:



  • sed: delete all occurrences of a string except the first one

    4 answers



I have some files in the format



Y15-SUB-B04-P17-BK_M02734_4_000000000-ANNUF_1_1111_24724_4878;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1111_20624_14973;size=1;
Y15-SUB-B05-P22-LM_M02734_4_000000000-ANNUF_1_1103_11326_10379;size=1;


I wish to replace every occurrence of the underscore (_) with a colon (:) EXCEPT for the first one. I want an output like this:



Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


I know I can use sed -i '' 's/_/:/g' old_file to replace ALL (or sed 's/_/:/g' old_file > new_file), and that I could add numbers to replace only the 2nd, 4th or so occurrence:



sed 's/_/:/2' old_file > new_file


But how to replace every occurrence on each line BUT the first?





This question already has an answer here:



  • sed: delete all occurrences of a string except the first one

    4 answers







text-processing sed






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 1 at 5:37









Inian

6,3651734




6,3651734










asked May 31 at 18:17









Christoffer Bugge HarderChristoffer Bugge Harder

684




684




marked as duplicate by αғsнιη, terdon sed
Users with the  sed badge can single-handedly close sed questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
12 hours ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by αғsнιη, terdon sed
Users with the  sed badge can single-handedly close sed questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
12 hours ago


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

    – 0xSheepdog
    May 31 at 18:20






  • 1





    Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

    – Christoffer Bugge Harder
    May 31 at 18:27






  • 4





    Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

    – 0xSheepdog
    May 31 at 18:31


















  • Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

    – 0xSheepdog
    May 31 at 18:20






  • 1





    Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

    – Christoffer Bugge Harder
    May 31 at 18:27






  • 4





    Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

    – 0xSheepdog
    May 31 at 18:31

















Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

– 0xSheepdog
May 31 at 18:20





Maybe a two step process? Replace all underscores with colons, then replace the first colon with an underscore?

– 0xSheepdog
May 31 at 18:20




1




1





Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

– Christoffer Bugge Harder
May 31 at 18:27





Sure, that would work, only my file is some 14+ gb, and each replacement process takes about 1 hour, so if there were just one parsing step, that would be preferable. Thank you though.

– Christoffer Bugge Harder
May 31 at 18:27




4




4





Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

– 0xSheepdog
May 31 at 18:31






Ah, so. Good info to have in the question, then. Things like requirements and limitations help us consider the entire situation.

– 0xSheepdog
May 31 at 18:31











7 Answers
7






active

oldest

votes


















10














Using GNU sed (other versions may behave differently, thanks glenn jackman):



 sed -i'' 's/_/:/2g' file


This will change all _ to : skipping the first occurrence on each line.






share|improve this answer




















  • 3





    This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

    – glenn jackman
    May 31 at 19:15






  • 1





    ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

    – G-Man
    Jun 3 at 3:25


















6














Using Posix-sed constructs only we do like as:



$ sed -e '
y/_/n/
s/n/_/
y/n/:/
' inp.file


Based on the suggestions by Stephane, some more methods follow here:



$ perl -pe 's/(^G.*?_)?.*?K_/:/g' inp.file 

$ perl -pe 'my $n; s/_/$n++?":":$&/ge' inp.file

$ perl -pe 's/_K(.*)/$1 =~ y|_|:|r/e' inp.file





share|improve this answer

























  • Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

    – Stéphane Chazelas
    Jun 1 at 6:43











  • This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

    – Rakesh Sharma
    yesterday











  • Yes, it was silly.

    – Stéphane Chazelas
    yesterday


















5














Is awk okay? You could use _ as the field separator, and print out:



<field 1>_<field 2>:<field n>:<field n+1>:...


Like this:



awk -F_ ' printf("%s_%s", $1, $2); for (x = 3; x <=NF; x++) printf(":%s", $x); ; printf("n"); '


If the structure is the same for each line you could hard-code the number of fields to avoid the loop (runs in about 2/3 of the time according to a very rough preliminary trial):



awk -F_ 'printf("%s_%s:%s:%s:%s:%s:%s:%sn", $1, $2, $3, $4, $5, $6, $7, $8);'





share|improve this answer

























  • Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

    – Christoffer Bugge Harder
    May 31 at 18:30






  • 1





    Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

    – drewbenn
    May 31 at 18:35






  • 1





    Note the sed commands in the other answers seem to be faster than either of these commands.

    – drewbenn
    May 31 at 18:50


















5














With perl, to match the character _ and replace from the first instance on-wards as below.



perl -pe '$n=0s_++$n > 1 ? ":" : $&;ge' file


The part s_ identifies the _ within the line and if its the 2nd occurrence replace with : or replace with the same character($&)






share|improve this answer






























    5














    Here is another simple awk script, (standard Linux gawk), no loops:



    cat script.awk
    match($0,/^[^_]*_/,a) # match current line to first _ (including) into a[0] variable
    sub(a[0],""); # remove a[0] from current line
    gsub("_",":"); # replace all _ to : in current line
    print a[0]""$0; # output a[0] and current line



    run:



    awk -f script.awk input.txt


    or:



    awk 'match($0,/^[^_]*_/,a)sub(a[0],"");gsub("_",":");print a[0]""$0;' input.txt





    share|improve this answer

























    • (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

      – G-Man
      Jun 3 at 3:32



















    2














    A simple sed command will work fine for this:



    Command: sed "s/_/:/2g" filename



    Output



    Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
    Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
    Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


    Note: Suppose if you want to replace in the same file, use the below command:



    sed -i "s/_/:/2g" filename





    share|improve this answer




















    • 2





      This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

      – Christoffer Bugge Harder
      May 31 at 20:17



















    1














    Given the sample input has no colon characters, a portable sed approach is to convert all underscores to colons, and then convert the first colon back to an underscore.



    sed 's/_/:/g;s/:/_/' filename


    @0xSheepdog sort of suggests this in the comments, but failed to point out this could be done with one invocation of sed.






    share|improve this answer























    • I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

      – G-Man
      Jun 3 at 3:39

















    7 Answers
    7






    active

    oldest

    votes








    7 Answers
    7






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    10














    Using GNU sed (other versions may behave differently, thanks glenn jackman):



     sed -i'' 's/_/:/2g' file


    This will change all _ to : skipping the first occurrence on each line.






    share|improve this answer




















    • 3





      This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

      – glenn jackman
      May 31 at 19:15






    • 1





      ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

      – G-Man
      Jun 3 at 3:25















    10














    Using GNU sed (other versions may behave differently, thanks glenn jackman):



     sed -i'' 's/_/:/2g' file


    This will change all _ to : skipping the first occurrence on each line.






    share|improve this answer




















    • 3





      This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

      – glenn jackman
      May 31 at 19:15






    • 1





      ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

      – G-Man
      Jun 3 at 3:25













    10












    10








    10







    Using GNU sed (other versions may behave differently, thanks glenn jackman):



     sed -i'' 's/_/:/2g' file


    This will change all _ to : skipping the first occurrence on each line.






    share|improve this answer















    Using GNU sed (other versions may behave differently, thanks glenn jackman):



     sed -i'' 's/_/:/2g' file


    This will change all _ to : skipping the first occurrence on each line.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 31 at 19:24

























    answered May 31 at 18:38









    FreddyFreddy

    4,2031420




    4,2031420







    • 3





      This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

      – glenn jackman
      May 31 at 19:15






    • 1





      ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

      – G-Man
      Jun 3 at 3:25












    • 3





      This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

      – glenn jackman
      May 31 at 19:15






    • 1





      ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

      – G-Man
      Jun 3 at 3:25







    3




    3





    This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

    – glenn jackman
    May 31 at 19:15





    This is GNU sed. Other sed implementations act differently when given both 2 and g (e.g. the BSD-derived sed on MacOS gives an error)

    – glenn jackman
    May 31 at 19:15




    1




    1





    ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

    – G-Man
    Jun 3 at 3:25





    ... and the POSIX specification says “If both g and n are specified, the results are unspecified.”

    – G-Man
    Jun 3 at 3:25













    6














    Using Posix-sed constructs only we do like as:



    $ sed -e '
    y/_/n/
    s/n/_/
    y/n/:/
    ' inp.file


    Based on the suggestions by Stephane, some more methods follow here:



    $ perl -pe 's/(^G.*?_)?.*?K_/:/g' inp.file 

    $ perl -pe 'my $n; s/_/$n++?":":$&/ge' inp.file

    $ perl -pe 's/_K(.*)/$1 =~ y|_|:|r/e' inp.file





    share|improve this answer

























    • Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

      – Stéphane Chazelas
      Jun 1 at 6:43











    • This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

      – Rakesh Sharma
      yesterday











    • Yes, it was silly.

      – Stéphane Chazelas
      yesterday















    6














    Using Posix-sed constructs only we do like as:



    $ sed -e '
    y/_/n/
    s/n/_/
    y/n/:/
    ' inp.file


    Based on the suggestions by Stephane, some more methods follow here:



    $ perl -pe 's/(^G.*?_)?.*?K_/:/g' inp.file 

    $ perl -pe 'my $n; s/_/$n++?":":$&/ge' inp.file

    $ perl -pe 's/_K(.*)/$1 =~ y|_|:|r/e' inp.file





    share|improve this answer

























    • Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

      – Stéphane Chazelas
      Jun 1 at 6:43











    • This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

      – Rakesh Sharma
      yesterday











    • Yes, it was silly.

      – Stéphane Chazelas
      yesterday













    6












    6








    6







    Using Posix-sed constructs only we do like as:



    $ sed -e '
    y/_/n/
    s/n/_/
    y/n/:/
    ' inp.file


    Based on the suggestions by Stephane, some more methods follow here:



    $ perl -pe 's/(^G.*?_)?.*?K_/:/g' inp.file 

    $ perl -pe 'my $n; s/_/$n++?":":$&/ge' inp.file

    $ perl -pe 's/_K(.*)/$1 =~ y|_|:|r/e' inp.file





    share|improve this answer















    Using Posix-sed constructs only we do like as:



    $ sed -e '
    y/_/n/
    s/n/_/
    y/n/:/
    ' inp.file


    Based on the suggestions by Stephane, some more methods follow here:



    $ perl -pe 's/(^G.*?_)?.*?K_/:/g' inp.file 

    $ perl -pe 'my $n; s/_/$n++?":":$&/ge' inp.file

    $ perl -pe 's/_K(.*)/$1 =~ y|_|:|r/e' inp.file






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday

























    answered May 31 at 20:16









    Rakesh SharmaRakesh Sharma

    679126




    679126












    • Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

      – Stéphane Chazelas
      Jun 1 at 6:43











    • This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

      – Rakesh Sharma
      yesterday











    • Yes, it was silly.

      – Stéphane Chazelas
      yesterday

















    • Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

      – Stéphane Chazelas
      Jun 1 at 6:43











    • This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

      – Rakesh Sharma
      yesterday











    • Yes, it was silly.

      – Stéphane Chazelas
      yesterday
















    Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

    – Stéphane Chazelas
    Jun 1 at 6:43





    Or perl -pe 's/(^G.*?_)?.*?K_/:/g' or perl -pe 'my $n; s/_/$n++?":":$&/ge' to do it in one s/// invocation only.

    – Stéphane Chazelas
    Jun 1 at 6:43













    This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

    – Rakesh Sharma
    yesterday





    This changes the first _ if the line has only one. Also, why the G placeholder? The ^ is sufficient or at least makes the G redundant.

    – Rakesh Sharma
    yesterday













    Yes, it was silly.

    – Stéphane Chazelas
    yesterday





    Yes, it was silly.

    – Stéphane Chazelas
    yesterday











    5














    Is awk okay? You could use _ as the field separator, and print out:



    <field 1>_<field 2>:<field n>:<field n+1>:...


    Like this:



    awk -F_ ' printf("%s_%s", $1, $2); for (x = 3; x <=NF; x++) printf(":%s", $x); ; printf("n"); '


    If the structure is the same for each line you could hard-code the number of fields to avoid the loop (runs in about 2/3 of the time according to a very rough preliminary trial):



    awk -F_ 'printf("%s_%s:%s:%s:%s:%s:%s:%sn", $1, $2, $3, $4, $5, $6, $7, $8);'





    share|improve this answer

























    • Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

      – Christoffer Bugge Harder
      May 31 at 18:30






    • 1





      Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

      – drewbenn
      May 31 at 18:35






    • 1





      Note the sed commands in the other answers seem to be faster than either of these commands.

      – drewbenn
      May 31 at 18:50















    5














    Is awk okay? You could use _ as the field separator, and print out:



    <field 1>_<field 2>:<field n>:<field n+1>:...


    Like this:



    awk -F_ ' printf("%s_%s", $1, $2); for (x = 3; x <=NF; x++) printf(":%s", $x); ; printf("n"); '


    If the structure is the same for each line you could hard-code the number of fields to avoid the loop (runs in about 2/3 of the time according to a very rough preliminary trial):



    awk -F_ 'printf("%s_%s:%s:%s:%s:%s:%s:%sn", $1, $2, $3, $4, $5, $6, $7, $8);'





    share|improve this answer

























    • Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

      – Christoffer Bugge Harder
      May 31 at 18:30






    • 1





      Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

      – drewbenn
      May 31 at 18:35






    • 1





      Note the sed commands in the other answers seem to be faster than either of these commands.

      – drewbenn
      May 31 at 18:50













    5












    5








    5







    Is awk okay? You could use _ as the field separator, and print out:



    <field 1>_<field 2>:<field n>:<field n+1>:...


    Like this:



    awk -F_ ' printf("%s_%s", $1, $2); for (x = 3; x <=NF; x++) printf(":%s", $x); ; printf("n"); '


    If the structure is the same for each line you could hard-code the number of fields to avoid the loop (runs in about 2/3 of the time according to a very rough preliminary trial):



    awk -F_ 'printf("%s_%s:%s:%s:%s:%s:%s:%sn", $1, $2, $3, $4, $5, $6, $7, $8);'





    share|improve this answer















    Is awk okay? You could use _ as the field separator, and print out:



    <field 1>_<field 2>:<field n>:<field n+1>:...


    Like this:



    awk -F_ ' printf("%s_%s", $1, $2); for (x = 3; x <=NF; x++) printf(":%s", $x); ; printf("n"); '


    If the structure is the same for each line you could hard-code the number of fields to avoid the loop (runs in about 2/3 of the time according to a very rough preliminary trial):



    awk -F_ 'printf("%s_%s:%s:%s:%s:%s:%s:%sn", $1, $2, $3, $4, $5, $6, $7, $8);'






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 31 at 18:34

























    answered May 31 at 18:25









    drewbenndrewbenn

    5,55451936




    5,55451936












    • Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

      – Christoffer Bugge Harder
      May 31 at 18:30






    • 1





      Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

      – drewbenn
      May 31 at 18:35






    • 1





      Note the sed commands in the other answers seem to be faster than either of these commands.

      – drewbenn
      May 31 at 18:50

















    • Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

      – Christoffer Bugge Harder
      May 31 at 18:30






    • 1





      Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

      – drewbenn
      May 31 at 18:35






    • 1





      Note the sed commands in the other answers seem to be faster than either of these commands.

      – drewbenn
      May 31 at 18:50
















    Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

    – Christoffer Bugge Harder
    May 31 at 18:30





    Thank you so much - I am unfortunately almost helpless in AWK, so I would have to be spoon-fed the exact command to make it work. if the first file is file1, and the second the output file (file2), then what should I write exactly? Sorry for my ineptitude.

    – Christoffer Bugge Harder
    May 31 at 18:30




    1




    1





    Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

    – drewbenn
    May 31 at 18:35





    Add file1 > file2 to the end of the command, to have it read in file1 and write out to file2. Just like you would with sed -- both parse text a line at a time!

    – drewbenn
    May 31 at 18:35




    1




    1





    Note the sed commands in the other answers seem to be faster than either of these commands.

    – drewbenn
    May 31 at 18:50





    Note the sed commands in the other answers seem to be faster than either of these commands.

    – drewbenn
    May 31 at 18:50











    5














    With perl, to match the character _ and replace from the first instance on-wards as below.



    perl -pe '$n=0s_++$n > 1 ? ":" : $&;ge' file


    The part s_ identifies the _ within the line and if its the 2nd occurrence replace with : or replace with the same character($&)






    share|improve this answer



























      5














      With perl, to match the character _ and replace from the first instance on-wards as below.



      perl -pe '$n=0s_++$n > 1 ? ":" : $&;ge' file


      The part s_ identifies the _ within the line and if its the 2nd occurrence replace with : or replace with the same character($&)






      share|improve this answer

























        5












        5








        5







        With perl, to match the character _ and replace from the first instance on-wards as below.



        perl -pe '$n=0s_++$n > 1 ? ":" : $&;ge' file


        The part s_ identifies the _ within the line and if its the 2nd occurrence replace with : or replace with the same character($&)






        share|improve this answer













        With perl, to match the character _ and replace from the first instance on-wards as below.



        perl -pe '$n=0s_++$n > 1 ? ":" : $&;ge' file


        The part s_ identifies the _ within the line and if its the 2nd occurrence replace with : or replace with the same character($&)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered May 31 at 18:53









        InianInian

        6,3651734




        6,3651734





















            5














            Here is another simple awk script, (standard Linux gawk), no loops:



            cat script.awk
            match($0,/^[^_]*_/,a) # match current line to first _ (including) into a[0] variable
            sub(a[0],""); # remove a[0] from current line
            gsub("_",":"); # replace all _ to : in current line
            print a[0]""$0; # output a[0] and current line



            run:



            awk -f script.awk input.txt


            or:



            awk 'match($0,/^[^_]*_/,a)sub(a[0],"");gsub("_",":");print a[0]""$0;' input.txt





            share|improve this answer

























            • (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

              – G-Man
              Jun 3 at 3:32
















            5














            Here is another simple awk script, (standard Linux gawk), no loops:



            cat script.awk
            match($0,/^[^_]*_/,a) # match current line to first _ (including) into a[0] variable
            sub(a[0],""); # remove a[0] from current line
            gsub("_",":"); # replace all _ to : in current line
            print a[0]""$0; # output a[0] and current line



            run:



            awk -f script.awk input.txt


            or:



            awk 'match($0,/^[^_]*_/,a)sub(a[0],"");gsub("_",":");print a[0]""$0;' input.txt





            share|improve this answer

























            • (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

              – G-Man
              Jun 3 at 3:32














            5












            5








            5







            Here is another simple awk script, (standard Linux gawk), no loops:



            cat script.awk
            match($0,/^[^_]*_/,a) # match current line to first _ (including) into a[0] variable
            sub(a[0],""); # remove a[0] from current line
            gsub("_",":"); # replace all _ to : in current line
            print a[0]""$0; # output a[0] and current line



            run:



            awk -f script.awk input.txt


            or:



            awk 'match($0,/^[^_]*_/,a)sub(a[0],"");gsub("_",":");print a[0]""$0;' input.txt





            share|improve this answer















            Here is another simple awk script, (standard Linux gawk), no loops:



            cat script.awk
            match($0,/^[^_]*_/,a) # match current line to first _ (including) into a[0] variable
            sub(a[0],""); # remove a[0] from current line
            gsub("_",":"); # replace all _ to : in current line
            print a[0]""$0; # output a[0] and current line



            run:



            awk -f script.awk input.txt


            or:



            awk 'match($0,/^[^_]*_/,a)sub(a[0],"");gsub("_",":");print a[0]""$0;' input.txt






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 3 at 2:51









            G-Man

            14.5k94175




            14.5k94175










            answered May 31 at 19:34









            Dudi BoyDudi Boy

            37127




            37127












            • (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

              – G-Man
              Jun 3 at 3:32


















            • (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

              – G-Man
              Jun 3 at 3:32

















            (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

            – G-Man
            Jun 3 at 3:32






            (1) sub() is not a great way to perform surgery on strings, because its first argument is a regular expression.  If the text before the first _ looks like a regular expression, this is likely to fail.  (2) You know that print a[0]""$0 can be written print a[0] $0 or print a[0]$0, right?  (It’s a matter of style.  I don’t particularly like the a[0]""$0 form, but it’s not wrong.)

            – G-Man
            Jun 3 at 3:32












            2














            A simple sed command will work fine for this:



            Command: sed "s/_/:/2g" filename



            Output



            Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


            Note: Suppose if you want to replace in the same file, use the below command:



            sed -i "s/_/:/2g" filename





            share|improve this answer




















            • 2





              This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

              – Christoffer Bugge Harder
              May 31 at 20:17
















            2














            A simple sed command will work fine for this:



            Command: sed "s/_/:/2g" filename



            Output



            Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


            Note: Suppose if you want to replace in the same file, use the below command:



            sed -i "s/_/:/2g" filename





            share|improve this answer




















            • 2





              This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

              – Christoffer Bugge Harder
              May 31 at 20:17














            2












            2








            2







            A simple sed command will work fine for this:



            Command: sed "s/_/:/2g" filename



            Output



            Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


            Note: Suppose if you want to replace in the same file, use the below command:



            sed -i "s/_/:/2g" filename





            share|improve this answer















            A simple sed command will work fine for this:



            Command: sed "s/_/:/2g" filename



            Output



            Y15-SUB-B04-P17-BK_M02734:4:000000000-ANNUF:1:1111:24724:4878;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1111:20624:14973;size=1;
            Y15-SUB-B05-P22-LM_M02734:4:000000000-ANNUF:1:1103:11326:10379;size=1;


            Note: Suppose if you want to replace in the same file, use the below command:



            sed -i "s/_/:/2g" filename






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jun 3 at 4:39









            Peter Mortensen

            93269




            93269










            answered May 31 at 18:38









            Praveen Kumar BSPraveen Kumar BS

            2,0432311




            2,0432311







            • 2





              This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

              – Christoffer Bugge Harder
              May 31 at 20:17













            • 2





              This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

              – Christoffer Bugge Harder
              May 31 at 20:17








            2




            2





            This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

            – Christoffer Bugge Harder
            May 31 at 20:17






            This gives me this error message: > sed: 1: "s/:/_/2g": more than one number or 'g' in substitute flags

            – Christoffer Bugge Harder
            May 31 at 20:17












            1














            Given the sample input has no colon characters, a portable sed approach is to convert all underscores to colons, and then convert the first colon back to an underscore.



            sed 's/_/:/g;s/:/_/' filename


            @0xSheepdog sort of suggests this in the comments, but failed to point out this could be done with one invocation of sed.






            share|improve this answer























            • I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

              – G-Man
              Jun 3 at 3:39















            1














            Given the sample input has no colon characters, a portable sed approach is to convert all underscores to colons, and then convert the first colon back to an underscore.



            sed 's/_/:/g;s/:/_/' filename


            @0xSheepdog sort of suggests this in the comments, but failed to point out this could be done with one invocation of sed.






            share|improve this answer























            • I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

              – G-Man
              Jun 3 at 3:39













            1












            1








            1







            Given the sample input has no colon characters, a portable sed approach is to convert all underscores to colons, and then convert the first colon back to an underscore.



            sed 's/_/:/g;s/:/_/' filename


            @0xSheepdog sort of suggests this in the comments, but failed to point out this could be done with one invocation of sed.






            share|improve this answer













            Given the sample input has no colon characters, a portable sed approach is to convert all underscores to colons, and then convert the first colon back to an underscore.



            sed 's/_/:/g;s/:/_/' filename


            @0xSheepdog sort of suggests this in the comments, but failed to point out this could be done with one invocation of sed.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 2 at 21:54









            icarusicarus

            6,83611632




            6,83611632












            • I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

              – G-Man
              Jun 3 at 3:39

















            • I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

              – G-Man
              Jun 3 at 3:39
















            I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

            – G-Man
            Jun 3 at 3:39





            I’m sure you know this, but, for the benefit of readers who aren’t as smart as you:  Warning: This will fail if any line of input has a colon (:) before the first underscore (_).

            – G-Man
            Jun 3 at 3:39



            Popular posts from this blog

            Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

            Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

            Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form