1

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.

4 Answers4

3
sed 'h;s/[^,]*,[^,]*,//
     y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
     H;x;s/[^,]*\n//

' foo.file
mikeserv
  • 58,310
2

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

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
0

The simple task do not require sed

while IFS=',' read -r first mid last
do
    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:]])
Costas
  • 14,916