Заглавные строки в sed или awk

У меня есть три типа строк, которые я хотел бы использовать в сценарии bash. Я решил, что sed/awk будет моим лучшим выбором, но я не уверен. Каков наилучший способ, учитывая следующие требования?

  1. одно слово
    например taco → Taco

  2. несколько слов, разделенных дефисом
    например, my-fish-tacos → My-Fish-Tacos

  3. несколько слов, разделенных символами подчеркивания
    например my_fish_tacos → My_Fish_Tacos

Ответы

Ответ 1

Нет необходимости использовать группы захвата (хотя & является одним из способов):

echo "taco my-fish-tacos my_fish_tacos" | sed 's/[^ _-]*/\u&/g'

Выход:

Taco My-Fish-Tacos My_Fish_Tacos

Скрытый нижний регистр "u" заглавный следующий символ в согласованной подстроке.

Ответ 2

Попробуйте следующее:

sed 's/\([a-z]\)\([a-z]*\)/\U\1\L\2/g'

Он работает для меня с помощью GNU sed, но я не думаю, что BSD sed поддерживает \U и \L.

Ответ 3

Использование awk:

echo 'test' | awk '{
     for ( i=1; i <= NF; i++) {
         sub(".", substr(toupper($i), 1,1) , $i);
         print $i;
         # or
         # print substr(toupper($i), 1,1) substr($i, 2);
     }
}'

Ответ 4

Вот решение, которое не использует \u, что не является общим для всех seds.

Сохраните этот файл в capitalize.sed, затем запустите sed -i -f capitalize.sed FILE

s:^:.:
h
y/qwertyuiopasdfghjklzxcvbnm/QWERTYUIOPASDFGHJKLZXCVBNM/ 
G 
s:$:\n:
:r
/^.\n.\n/{s:::;p;d}
/^[^[:alpha:]][[:alpha:]]/ {
    s:.\(.\)\(.*\):x\2\1: 
    s:\n\(..\):\nx: 
    tr
}

/^[[:alpha:]][[:alpha:]]/ {
    s:\n.\(.\)\(.*\)$:\nx\2\1:
    s:..:x:
    tr
}
/^[^\n]/ {
    s:^.\(.\)\(.*\)$:.\2\1:
    s:\n..:\n.:
    tr
}

Ответ 5

Это может сработать для вас (GNU sed):

echo "aaa bbb ccc aaa-bbb-ccc aaa_bbb_ccc aaa-bbb_ccc"  | sed 's/\<.\|_./\U&/g'
Aaa Bbb Ccc Aaa-Bbb-Ccc Aaa_Bbb_Ccc Aaa-Bbb_Ccc

Ответ 6

alinsoar mind-blowing solution не работает вообще в Plan9 sed, или правильно в busybox sed. Но вы все равно должны попытаться выяснить, как он должен это делать: вы узнаете много о sed.

Здесь не-умная, но понятная версия, которая работает, по крайней мере, в Plan9, busybox и GNU sed (и, вероятно, BSD и MacOS). Команда Plan9 sed требует обратной обратной косой черты в совпадающей части команды s.

#! /bin/sed -f

y/PYFGCRLAOEUIDHTNSQJKXBMWVZ/pyfgcrlaoeuidhtnsqjkxbmwvz/

s/\(^\|[^A-Za-z]\)a/\1A/g
s/\(^\|[^A-Za-z]\)b/\1B/g
s/\(^\|[^A-Za-z]\)c/\1C/g
s/\(^\|[^A-Za-z]\)d/\1D/g
s/\(^\|[^A-Za-z]\)e/\1E/g
s/\(^\|[^A-Za-z]\)f/\1F/g
s/\(^\|[^A-Za-z]\)g/\1G/g
s/\(^\|[^A-Za-z]\)h/\1H/g
s/\(^\|[^A-Za-z]\)i/\1I/g
s/\(^\|[^A-Za-z]\)j/\1J/g
s/\(^\|[^A-Za-z]\)k/\1K/g
s/\(^\|[^A-Za-z]\)l/\1L/g
s/\(^\|[^A-Za-z]\)m/\1M/g
s/\(^\|[^A-Za-z]\)n/\1N/g
s/\(^\|[^A-Za-z]\)o/\1O/g
s/\(^\|[^A-Za-z]\)p/\1P/g
s/\(^\|[^A-Za-z]\)q/\1Q/g
s/\(^\|[^A-Za-z]\)r/\1R/g
s/\(^\|[^A-Za-z]\)s/\1S/g
s/\(^\|[^A-Za-z]\)t/\1T/g
s/\(^\|[^A-Za-z]\)u/\1U/g
s/\(^\|[^A-Za-z]\)v/\1V/g
s/\(^\|[^A-Za-z]\)w/\1W/g
s/\(^\|[^A-Za-z]\)x/\1X/g
s/\(^\|[^A-Za-z]\)y/\1Y/g
s/\(^\|[^A-Za-z]\)z/\1Z/g