Replace only first instance of a character
Solution 1
Pure bash solution
while IFS=\, read -r a b ; do echo "$a;$b" ; done <file.csv
Or just for fun
paste -d\; <(cut -d, -f1 file.csv) <(cut -d, -f1 --complement file.csv)
Solution 2
The g
in:
sed 's/,/;/g'
is for globally, that is to substitute all occurrences of ,
with ;
.
If you want to do only one substitution per line, take off the g
:
sed 's/,/;/'
And for completeness:
You can also specify which occurrence to substitute. For instance, to substitute only the second occurrence:
sed 's/,/;/2'
With GNU sed
, you can also substitute all occurrences starting from the second one (in effect, all but the first one) with:
sed 's/,/;/2g'
To perform two substitutions, in this case:
sed 's/,/;/;s/,/;/'
Where it gets more complicated is when the pattern can match the substitution (or parts of it), for instance when substituting ,
with <,>
. sed
has no built-in mechanism to address that. You may want to use perl
instead in that case:
perl -pe '$i = 0; s/,/$i++ < 2 ? "<,>" : $&/ge'
perl -pe
is perl
's sed
mode (note that the regex syntax is different). With the e
flag of the s///
operator, the replacement is considered as code. There, we replace ,
with <,>
only when our incremented counter is < 2. Otherwise, we replace the ,
with itself ($&
actually referring to the matched string like &
in sed
's s
command).
You can generalise that for a range or set of substitutions. Like for 3rd to 5th and 7th to 9th:
perl -pe '$i = 0; s/,/$i++;
$i >=3 && $i <= 5 || $i >= 7 && $i <= 9 ? "<,>" : $&/ge'
To replace only the first occurrence in the whole input (as opposed to in each line):
sed -e 's/,/;/;t done' -e b -e :done -e 'n;b done'
That is, upon the first successful substitution, go into a loop that just prints the rest of the input.
With GNU sed
, you can use the pseudo address 0:
sed '0,/,/s//;/'
Note
I suppose it's a typo, but the
sed '/s/,/;/g'
command you wrote in your question is something completely different.
That's doing:
sed '/start/,/end/g'
where start
is s
and end
is ;
. That is, applying the g
command (replace the pattern space with the content of the hold space (empty here as you never hold anything)) for sections of the file in between one that contains s
and the next one that contains ;
.
Related videos on Youtube
Guforu
Updated on September 18, 2022Comments
-
Guforu over 1 year
for example I have scv file which looks like
a1, b1, c1, d1 a2, b2, c2, d2 a3, b3, c3, d3
What I want to do is to replace the first comma
,
with the semicolon;
. The position of first comma can be variable (a
in the rowsn
andm
can have different lengths). Finally my file shall look likea1; b1, c1, d1 a2; b2, c2, d2 a3; b3, c3, d3
The other commas have to remain. Can somebody please tell me the most simple solution?
PS my solution doesn't work:
sed '/s/,/;/g' file.csv
-
Costas almost 8 yearsDo
sed 's/,/;/' file.csv
satisfy you? -
Guforu almost 8 yearsno, I have got next error message: sed: -e expression #1, char 7: missing command
-
Costas almost 8 yearsDo you miss quotes?
-
Stéphane Chazelas almost 8 years@Gufory,
g
is to change all comas. Without it, it changes only the first. See alsosed 's/,/;/2'
to change the second only and with GNUsed
,sed 's/,/;/2g'
to change all but the first. -
Costas almost 8 yearsWith
g
sed change all commas in line, without it - just first. It cannot be truesed "s/,/;/g"
do work andsed "s/,/;/"
gets error. If you sence with sed trywhile IFS=\, read a b ; do echo "$a;$b" ; done <file.csv
-
Guforu almost 8 yearsWow, this is exactly the solution! Now is everything works! Thank you a lot!
-
ygreaney almost 8 yearsI"ve submitted an edit (peer-review pending) to change the title, as this explicitly is NOT about a specific position, but about the first occurrence, of the character.
-
-
Stéphane Chazelas almost 8 yearsTry the first one on an input like
1,2,
or1\,2
or1
. See also Why is using a shell loop to process text considered bad practice? -
Costas almost 8 years@StéphaneChazelas Thank you for comment, I have -r option added.
-
Stéphane Chazelas almost 8 yearsgood. That addresses
1\,2
, but not the1,2,
or1
cases though. Note that,
is not special, you don't need to quote it. -
Nux over 5 yearsNote that to only replace 1st occurence in a file (not in a line) you need to do something else. See: linuxconfig.org/…
-
Stéphane Chazelas over 5 years@Nux. Thanks, I've added a section about that.