4

This question already has an answer here:

Example Input:

foobar@example.com foo@example.com,bar@example.com

Example Output:

foobar@example.org foo@example.com,bar@example.com

So, in "normal" circumstances, it would obviously be easy to do something like:

sed 's/.com/.org/g'

But obviously in this case, I only want the suffix in the first column to be manipulated, I want the second column to be left untouched.

I don't mind what tool you propose to use. But I prefer it to available on a standard linux without needing further install (i.e. something like sed or awk or perl would be more preferable to bobsobscuretoolthatneedsinstalling).

marked as duplicate by Jeff Schaller, RalfFriedl, Stephen Harris, jimmij, DarkHeart Dec 12 '18 at 6:03

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.

  • 2
    Why not just leave off the "g" at the end of the sed command? Then it will only replace the first occurrence... – twalberg Dec 11 '18 at 16:46
  • @twalberg What if the first column has no .com but the second does? – Nic Hartley Dec 11 '18 at 18:22
  • @NicHartley Valid point in general, in which case I would use something like the accepted awk solution. But, it doesn't match the supplied sample input, which may or may not mean anything... – twalberg Dec 11 '18 at 18:23
4
$ awk '{ sub("\.com$", ".org", $1); print }' <file
foobar@example.org foo@example.com,bar@example.com

This uses awk to substitute the text matched by \.com$ with .org in the first whitespace-delimited field (only) of each line. The output will be space-delimited.

5

If you just want to replace the first occurrence of .com with .org, all you need is the default behavior of sed's s/// operator. Just don't use the g flag:

$ sed 's/.com/.org/' file 
foobar@example.org foo@example.com,bar@example.com

If you really want to only make the change on the first comma-defined field, so that if the first .com appears elsewhere in the line, it will remain unchanged, you can do something like:

$ perl -pe 's/^(\S+)\.com/$1.org/' file 
foobar@example.org foo@example.com,bar@example.com

Or, safer in case com occurs as a substring (e.g. foo.common.net):

$ perl -pe 's/^(\S+)\.com\b/$1.org/' file 
foobar@example.org foo@example.com,bar@example.com

Alternatively, in GNU sed:

$ sed -E 's/^(\S+)\.com\b/\1.org/' file 
foobar@example.org foo@example.com,bar@example.com

Or, portably (assuming the first field is defined by the first space and not a tab or other whitespace):

$ sed -E 's/^([^ ])\.com /\1.org /' file 
foobar@example.org foo@example.com,bar@example.com
4

You can do it using sed, just use a regexp that can only match the first word of the line:

sed -r 's/^(\S+)\.com(\s+)/\1.org\2/'

In slo-mo, change:

  1. a sequence of one or more non-spaces from the beginning (^(\S+))
  2. .com
  3. a sequence of one or more non spaces (so that we can only match a final .com)

into:

  1. the first sequence of non-spaces
  2. .org
  3. the sequence of spaces
  • Not using the /g doesn't prevent the substitution to occur in other items of the line if it doesn't happen on the first. And capturing the final \s+ insures that we aren't replacing .com in the middle of a node id such as some.commonname.com. – xenoid Dec 11 '18 at 10:47
  • Note that the use of PCRE requires GNU sed. – Kusalananda Dec 11 '18 at 12:04
  • OP asked for "standard Linux" :) – xenoid Dec 11 '18 at 12:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.