7

I got the following text:

Lorem ipsum dolor sit amet, consectetur adipisicing elit.

That I want to capitalize, i.e. uppercase first letter of every word.

Expected result

Lorem Ipsum Dolor Sit Amet, Consectetur Adipisicing Elit.

Bash equivalent

Using bash, I was using a parameter expansion:

function to-lower() { echo "$@" |tr '[:upper:]' '[:lower:]' ; }

function capitalize() {
    input="$(to-lower "$@")"
    for i in $input; do
        cap=$(echo -n "${i:0:1}" | tr "[:lower:]" "[:upper:]")
        echo -n "${cap}${i:1} "
    done
    echo
}

Question

How do I do that in a fish-way?

Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178

4 Answers4

2

Fish currently doesn't have any tools to do this (in a release), so assuming you have GNU sed you can do this:

function capitalize
    echo $argv | sed 's/[^ _-]*/\u&/g'
end

There are also a variety of other tools, you can also do it with e.g. python or by calling bash from fish, the point is that there is no way to either extract a substring or replace a character with fish builtins.

In the next fish release, you'll be able to use string sub -l 1 $i to extract the first character.

faho
  • 14,470
  • 2
  • 37
  • 47
1

Solution using external tool (from commandlinefu)

function capitalize
    set input "$argv"
    echo "$input" | tr '[A-Z]' '[a-z]' | sed 's/\(^\| \)\([a-z]\)/\1\u\2/g'
end

Usage

capitalize "Lorem ipsum dolor sit amet, consectetur adipisicing elit."                                                                        

Lorem Ipsum Dolor Sit Amet, Consectetur Adipisicing Elit.

Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178
1

You can use string replace with regular expressions to achieve this:

$ string replace -r -a '\b([\w])' '\U$0' "Lorem ipsum dolor sit amet, consectetur adipisicing elit."
Lorem Ipsum Dolor Sit Amet, Consectetur Adipisicing Elit.

Wait, forgot to escape a space. Wheeeeee[taptaptap]eeeeee.

Adam Lindberg
  • 16,447
  • 6
  • 65
  • 85
  • 1
    This is the correct answer. I'm surprised the answer would ever be to use `sed` for a fish question. I always recommend `string`. – mattmc3 Jan 13 '23 at 21:49
0

None of the previous solutions work for me. It seems that sed doesn't works well in my machine. If anyone experiences any similar problem this is the workaround I've finally used:

function title_case -a string
  set -l matches (string match -r -a '\b[a-z]' $string)

  for match in $matches
    set -l upper (echo $match | tr a-z A-Z)
    set string (echo (string replace -r '\b[a-z]' $upper $string))
  end

  echo $string
end

Only works in fish 2.3.0 or newer versions due I'm using the string builtin

Alex Guerrero
  • 2,109
  • 1
  • 19
  • 28
  • I've tried it now and it seems to works as expected, the user wants a variation of Title Case - without exceptions for the, and... - and that's how this function works. Maybe what you want is a something like a Upper case function? if that's not the case what version of fish shell are you using? – Alex Guerrero Nov 28 '16 at 23:00
  • yep, my mistake. though it was TOUPPER. – Olivier Refalo Dec 02 '16 at 09:02