4

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).

4
  • 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, 2018 at 16:46
  • @twalberg What if the first column has no .com but the second does?
    – Nic
    Dec 11, 2018 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, 2018 at 18:23

3 Answers 3

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
0
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.

0
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
3
  • 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, 2018 at 10:47
  • Note that the use of PCRE requires GNU sed.
    – Kusalananda
    Dec 11, 2018 at 12:04
  • OP asked for "standard Linux" :)
    – xenoid
    Dec 11, 2018 at 12:54

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