Replace spaces with comma but not in the whole line

some name;another thing; random; value value value value value

I’m trying to replace the spaces that occur after the random; using sed. It’s important to keep the spaces that is in some name for example.

This replaces all spaces with comma. How could I match a expression like *;*;*; and use sed with the rest of the line and replace spaces with comma?

sed -e 's/ /,/g'


Asked By: JoakimE


With GNU sed

$ s='some name;another thing; random; value value value value value'
$ echo "$s" | sed -E ':a s/^(.*random;.*) /1,/; ta'
some name;another thing; random;,value,value,value,value,value
  • :a label a
  • s/^(.*random;.*) /1,/ here (.*random;.*) will capture everything till random; in the input line and as many characters as needed till there is a space afterwards, then in the replacement section use backreference to preserve the captured string and change space to comma character
    • note that if there are more than one random; in the input, this will preserve spaces only till the first occurrence
  • ta branch to label a if the previous substitution succeeded
Answered By: Sundeep

Perl to the rescue!

perl -F';' -ne '$F[3] =~ s/ /,/g; print join ";", @F'
  • -n reads the input line by line and process each line
  • -F splits each line on the given regular expression into the @F array
  • =~ binds the substitution only to the fourth element of the @F array, i.e. after the element after “random”
  • join joins back the elements of the @F array into the output string
Answered By: choroba

Using gsub() in awk on the last ;-delimited field:

$ awk -F ';' 'BEGIN { OFS=FS } { gsub(" ", ",", $NF); print }' file
some name;another thing; random;,value,value,value,value,value

Using sed and assuming we’d like to replace all spaces after the last ; with commas:

$ sed 'h;s/.*;//;y/ /,/;x;s/;[^;]*$//;G;s/n/;/' file
some name;another thing; random;,value,value,value,value,value

Annotated sed script:

h               ; # Duplicate line into hold space
s/.*;//         ; # Delete up to the last ;
y/ /,/          ; # Change space to comma in remaining data
x               ; # Swap pattern and hold spaces
s/;[^;]*$//     ; # Delete from the last ;
G               ; # Append hold space delimited by newline
s/n/;/         ; # Replace the embedded newline with ;
                ; # (implicit print)

The “hold space” is a separate storage buffer that sed provides. The “pattern space” is the buffer into which the data is read from the input and to which modifications may be applied.

Answered By: Kusalananda
$ perl -MText::CSV_XS=csv -e'csv(in=>csv(in=>"file",sep=>";",allow_whitespace=>1),sep=>";",quote_space=>0);'
some name;another thing;random;value value value value value
Answered By: Tux
$ perl -pe 's/ (?=[^;]*$)/,/g' file
  • Only those spaces that don’t see a semicolon all the way to the end of line are selected for substitution.
Answered By: Rakesh Sharma
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.