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;
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?
text-processing sed
marked as duplicate by αғsнιη, terdon♦
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.
add a comment |
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?
text-processing sed
marked as duplicate by αғsнιη, terdon♦
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
add a comment |
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?
text-processing sed
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
text-processing sed
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♦
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♦
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
add a comment |
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
add a comment |
7 Answers
7
active
oldest
votes
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.
3
This is GNU sed. Other sed implementations act differently when given both2
andg
(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
add a comment |
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
Orperl -pe 's/(^G.*?_)?.*?K_/:/g'
orperl -pe 'my $n; s/_/$n++?":":$&/ge'
to do it in ones///
invocation only.
– Stéphane Chazelas
Jun 1 at 6:43
This changes the first _ if the line has only one. Also, why theG
placeholder? The^
is sufficient or at least makes theG
redundant.
– Rakesh Sharma
yesterday
Yes, it was silly.
– Stéphane Chazelas
yesterday
add a comment |
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);'
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
Addfile1 > file2
to the end of the command, to have it read in file1 and write out to file2. Just like you would withsed
-- 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
add a comment |
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($&
)
add a comment |
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
(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 thatprint a[0]""$0
can be writtenprint a[0] $0
orprint a[0]$0
, right? (It’s a matter of style. I don’t particularly like thea[0]""$0
form, but it’s not wrong.)
– G-Man
Jun 3 at 3:32
add a comment |
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
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
add a comment |
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
.
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
add a comment |
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
3
This is GNU sed. Other sed implementations act differently when given both2
andg
(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
add a comment |
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.
3
This is GNU sed. Other sed implementations act differently when given both2
andg
(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
add a comment |
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.
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.
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 both2
andg
(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
add a comment |
3
This is GNU sed. Other sed implementations act differently when given both2
andg
(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
add a comment |
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
Orperl -pe 's/(^G.*?_)?.*?K_/:/g'
orperl -pe 'my $n; s/_/$n++?":":$&/ge'
to do it in ones///
invocation only.
– Stéphane Chazelas
Jun 1 at 6:43
This changes the first _ if the line has only one. Also, why theG
placeholder? The^
is sufficient or at least makes theG
redundant.
– Rakesh Sharma
yesterday
Yes, it was silly.
– Stéphane Chazelas
yesterday
add a comment |
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
Orperl -pe 's/(^G.*?_)?.*?K_/:/g'
orperl -pe 'my $n; s/_/$n++?":":$&/ge'
to do it in ones///
invocation only.
– Stéphane Chazelas
Jun 1 at 6:43
This changes the first _ if the line has only one. Also, why theG
placeholder? The^
is sufficient or at least makes theG
redundant.
– Rakesh Sharma
yesterday
Yes, it was silly.
– Stéphane Chazelas
yesterday
add a comment |
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
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
edited yesterday
answered May 31 at 20:16
Rakesh SharmaRakesh Sharma
679126
679126
Orperl -pe 's/(^G.*?_)?.*?K_/:/g'
orperl -pe 'my $n; s/_/$n++?":":$&/ge'
to do it in ones///
invocation only.
– Stéphane Chazelas
Jun 1 at 6:43
This changes the first _ if the line has only one. Also, why theG
placeholder? The^
is sufficient or at least makes theG
redundant.
– Rakesh Sharma
yesterday
Yes, it was silly.
– Stéphane Chazelas
yesterday
add a comment |
Orperl -pe 's/(^G.*?_)?.*?K_/:/g'
orperl -pe 'my $n; s/_/$n++?":":$&/ge'
to do it in ones///
invocation only.
– Stéphane Chazelas
Jun 1 at 6:43
This changes the first _ if the line has only one. Also, why theG
placeholder? The^
is sufficient or at least makes theG
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
add a comment |
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);'
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
Addfile1 > file2
to the end of the command, to have it read in file1 and write out to file2. Just like you would withsed
-- 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
add a comment |
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);'
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
Addfile1 > file2
to the end of the command, to have it read in file1 and write out to file2. Just like you would withsed
-- 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
add a comment |
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);'
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);'
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
Addfile1 > file2
to the end of the command, to have it read in file1 and write out to file2. Just like you would withsed
-- 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
add a comment |
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
Addfile1 > file2
to the end of the command, to have it read in file1 and write out to file2. Just like you would withsed
-- 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
add a comment |
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($&
)
add a comment |
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($&
)
add a comment |
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($&
)
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($&
)
answered May 31 at 18:53
InianInian
6,3651734
6,3651734
add a comment |
add a comment |
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
(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 thatprint a[0]""$0
can be writtenprint a[0] $0
orprint a[0]$0
, right? (It’s a matter of style. I don’t particularly like thea[0]""$0
form, but it’s not wrong.)
– G-Man
Jun 3 at 3:32
add a comment |
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
(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 thatprint a[0]""$0
can be writtenprint a[0] $0
orprint a[0]$0
, right? (It’s a matter of style. I don’t particularly like thea[0]""$0
form, but it’s not wrong.)
– G-Man
Jun 3 at 3:32
add a comment |
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
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
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 thatprint a[0]""$0
can be writtenprint a[0] $0
orprint a[0]$0
, right? (It’s a matter of style. I don’t particularly like thea[0]""$0
form, but it’s not wrong.)
– G-Man
Jun 3 at 3:32
add a comment |
(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 thatprint a[0]""$0
can be writtenprint a[0] $0
orprint a[0]$0
, right? (It’s a matter of style. I don’t particularly like thea[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
add a comment |
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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
.
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
add a comment |
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
.
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
add a comment |
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
.
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
.
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
add a comment |
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
add a comment |
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