Reputation: 43
OK, I'll explain with an example:
echo "x,y (fifo(x,y) , q(x) , fifo(z))" | sed 's/f\([a-z]*\)/F\1/g'
output: x,y (Fifo(x,y) , q(x) , Fifo(z))
So basically I want to match on every word (letters only) that ends with a "(", and change the first letter of that word to uppercase. My code doesn't really work because I'd like "q(x)" to become "Q(x)" too.
In my example I do this manually by specifing "f" and "F" in the sed command (which means that it doesn't work for "q(x)") - is there a way to do this without repeating the same command for every letter in the alphabet?
GNU sed seems to have a way of making a letter uppercase, but I don't think it's supported on mac.
Thanks!
Upvotes: 2
Views: 491
Reputation: 203684
With GNU sed for \u
to convert the next letter to upper case:
$ echo "x,y (fifo(x,y) , q(x) , fifo(z))" | sed -E 's/(\w)(\w*\()/\u\1\2/g'
x,y (Fifo(x,y) , Q(x) , Fifo(z))
You can install GNU sed on macOS. Othewrise with any POSIX awk:
$ cat tst.awk
{
head = ""
while ( match($0,/[[:alpha:]]+\(/) ) {
head = head substr($0,1,RSTART-1) toupper(substr($0,RSTART,1)) substr($0,RSTART+1,RLENGTH-1)
$0 = substr($0,RSTART+RLENGTH)
}
print head $0
}
$ echo "x,y (fifo(x,y) , q(x) , fifo(z))" | awk -f tst.awk
x,y (Fifo(x,y) , Q(x) , Fifo(z))
Upvotes: 3
Reputation: 5252
For fun, figured out a macOS sed
solution, the mechanism is to use a loop to switch pattern to line beginning, and uppercase first letter, then switch back.(using \r
to separate)
It will be too long so I'll skip to transfer it to a one-liner.
Also it only uppercase first letter in pattern, won't lowercase following letters, so it's not strictly speaking a capitalize function. However using similar mechanism it can be done.
echo "x,y (fifo(x,y) , q(x) , fifo(z))" | sed -e '
/^[a-z][a-z]*(/breplace
:circle
/[^a-zA-Z][a-z][a-z]*(/!bend
s/\(.*[^a-zA-Z]\)\([a-z][a-z]*(.*\)/\2\r\1/
:replace
s/^a/A/
s/^b/B/
s/^c/C/
s/^d/D/
s/^e/E/
s/^f/F/
s/^g/G/
s/^h/H/
s/^i/I/
s/^j/J/
s/^k/K/
s/^l/L/
s/^m/M/
s/^n/N/
s/^o/O/
s/^p/P/
s/^q/Q/
s/^r/R/
s/^s/S/
s/^t/T/
s/^u/U/
s/^v/V/
s/^w/W/
s/^x/X/
s/^y/Y/
s/^z/Z/
/\r/s/\(.*\)\r\(.*\)/\2\1/
bcircle
:end
'
Output:
x,y (Fifo(x,y) , Q(x) , Fifo(z))
If anyone wondering, I didn't type those s
es manually,
I use awk 'BEGIN{for(i=97;i<123;i++)printf "s/^%c/%c/\n", i, i-32}'
created them.
Upvotes: 2
Reputation: 5252
It's not impossible but it's a quite hard thing for the sed
on macos to do it.
Why not change to use ruby
instead?(afaik ruby
is preinstalled on macos, right?)
Try this:
echo "x,y (fIfo(x,y) , q(x) , fifo(z))" | ruby -ne 'print $_.gsub(/([a-z]+)(?=\()/i){$1.capitalize}'
Output:
x,y (Fifo(x,y) , Q(x) , Fifo(z))
Notice I changed to fIfo
in the echo, and used i
flag to ruby's regex for caseinsensitve.
Upvotes: 2