2

Let say I have this list:

39dd809b7a36
d83f42ab46a9
9664e29ac67c
66cf165f7e32
51b9394bc3f0

I want to convert the first occurrence of alphabet to uppercase, for example

39dd809b7a36 -> 39Dd809b7a36

bash/awk/sed solution should be ok.

Thanks for the help.

5
  • Hi, I found my own solution after playing with sed regex for a while. The solution is sed 's/\([a-z]\)/\U\1/' sample: optimus:~# echo "96f795e4370a > bfe6f5e05416 > 5f70a4463d79 > decab73017db > a136f8c01c18 > " | sed 's/\([a-z]\)/\U\1/' 96F795e4370a Bfe6f5e05416 5F70a4463d79 Decab73017db A136f8c01c18 Hopefully people will find it useful. Other solutions is interesting as well. :) Commented May 31, 2011 at 3:30
  • I would expect this to work on most sed versions. surprised to hear OSX doesn't .... :> echo bfe6f5e05416 | sed 's/([a-z])/\U\1/' result=Bfe6f5e05416 ....:>sed --version result=GNU sed version 4.2.1 Commented May 31, 2011 at 3:51
  • yes. mine is GNU sed. optimus:~# sed --version GNU sed version 4.1.5 this page mention that \U is GNU extension: http://www.gnu.org/software/sed/manual/sed.html Commented May 31, 2011 at 3:55
  • @sharuzzaman-ahmat-raslan add your solution as a proper answer so it can be accepted and thus removed from the unanswered problems Commented May 31, 2011 at 8:09
  • @fredrik I cannot add yet because I just joined less than 6 hours ago. will add by tomorrow Commented May 31, 2011 at 8:48

4 Answers 4

4

GNU sed can do it

printf "%s\n" 39dd809b7a36 d83f42ab46a9 9664e29ac67c 66cf165f7e32 51b9394bc3f0 |
sed 's/[[:alpha:]]/\U&/'

gives

39Dd809b7a36
D83f42ab46a9
9664E29ac67c
66Cf165f7e32
51B9394bc3f0
Sign up to request clarification or add additional context in comments.

Comments

1

Pure Bash 4.0+ using parameter substitution:

string=( "39dd809b7a36" "d83f42ab46a9"
         "9664e29ac67c" "66cf165f7e32" "51b9394bc3f0" )

for str in ${string[@]}; do
  # get the leading digits by removing everything
  # starting from the first letter:
  head="${str%%[a-z]*}"
  # and the rest of the string starting with the first letter
  tail="${str:${#head}}"
  # compose result : head + tail with 1. letter to upper case
  result="$head${tail^}"

  echo -e "$str\n$result\n"
done

Result:

39dd809b7a36
39Dd809b7a36

d83f42ab46a9
D83f42ab46a9

9664e29ac67c
9664E29ac67c

66cf165f7e32
66Cf165f7e32

51b9394bc3f0
51B9394bc3f0

Comments

1

I can't think of any clever way to do this with the basic SW tools, but the BFI solution isn't too bad.

In the One True awk(1) or in gawk:

{ n = split($0, a, "")
  for(i = 1; i <= n; ++i) {
    s = a[i]
    t = toupper(s)
    if (s != t) {
      a[i] = t
      break
    }
  }
  r = ""
  for(i = 1; i <= n; ++i) {
    r = r a[i]
  }
  print r
}

It's not too bad in Ruby:

ruby -p -e '$_ = $_.split(/(?=[a-z])/, 2); $_[1].capitalize!'

Comments

1

Here is my solution. It will not allow patterns in form ###.### but can be tweaked as needed.

A=$(cat); B=$(echo $A | sed 's/([a-z])/###\1###/' | sed 's/.###(.)###./\1/' | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/') ; C="echo $A | sed 's/[a-z]/$B/'" ; eval $C

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.