I've got three comma separated columns. Last name, First name, social.

I'm trying to capitalize all characters in the last name column using

sed 's/\([^,]*\)/\U\1/' foo.file

In osx this command is appending a capital U to the beginning of each line, rather than capitalizing the Last name column, but it works as expected on my ubuntu instance.

I cannot figure out why this is happening.

The man page lists a bug "Multibyte characters cannot be used as delimiters with the ''s'' and ''y'' commands. I wasn't sure if / was a multibyte character or not (didn't think that it was), but the same thing happens if I replace the delimiter with 'i'. So this isn't the issue.

sed 'h;s/[^,]*,[^,]*,//

' foo.file

\U is a GNUism, actually inspired from a BSDism since that comes from the equivalent s command in the ex editor (command-line mode of vi).

OS/X sed most likely descends from FreeBSDs itself descending from 4.4BSD's sed, which was rewritten from scratch following copyright issues with AT&T. In any case, neither BSD nor AT&T sed support \U in their s command.

To convert to uppercase, in sed portably, you generally use the y command as already shown.

But here a better approach is probably to use awk instead:

awk -F, -vOFS=, '{$1 = toupper($1); print}'
  • All of that Unix wars stuff really set the Unix world back - a lot. As I see it, it began with the unchecked fragmentation of the platform, and ended with it nearly being pulled completely apart. The lesson I take from it is that, while innovation is a good thing in that it brings improvement, without a basic standard a computing ecosystem is doomed to failure. It's why I advocate POSIX - it seems to me the surest way forward the Unix world as a whole. – mikeserv Apr 11 '15 at 20:02

The simple task do not require sed

while IFS=',' read -r first mid last
    echo "$first, $mid, ${last^^}"
done < file_with_commas

If bash version do not support variable expansion you can use tr

last=$(echo $last | tr [[:lower:]] [[:upper:]])

Seems /U and /L just do not work with OSX/BSD sed

along with

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a shell command
sed -n l0 # 0 disables wrapping

Thank you guys. My reputation isn't high enough to upvote yet, but Mike you solved my problem with sed, and I agree with Stephane. Awk seems to be the better choice.

  • That's not a hack - that's a character translation. It's not the same as a regular expression - it's like tr. That's what the y/// command does. – mikeserv Apr 11 '15 at 10:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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