sed help - преобразовать строку формы ABC_DEF_GHI в AbcDefGhi - PullRequest
0 голосов
/ 27 декабря 2010

Как можно преобразовать строку формы ABC_DEF_GHI в AbcDefGhi с помощью любой онлайн-команды, такой как sed и т. Д.?

Ответы [ 6 ]

1 голос
/ 29 декабря 2010

Оптимизировано awk 1-лайнер

awk -v RS=_ '{printf "%s%s", substr($0,1,1), tolower(substr($0,2))}'

Оптимизировано sed 1-лайнер

sed 's/\(.\)\(..\)_\(.\)\(..\)_\(.\)\(..\)/\1\L\2\U\3\L\4\U\5\L\6/'
1 голос
/ 27 декабря 2010

Вот одна строка с использованием gawk:

echo ABC_DEF_GHI | gawk 'function cap(s){return toupper(substr(s,1,1))tolower(substr(s,2))}{n=split($0,x,"_");for(i=1;i<=n;i++)o=o cap(x[i]); print o}'

AbcDefGhi

0 голосов
/ 12 декабря 2011

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

echo "ABC_DEF_GHI" | 
sed 'h;s/\(.\)[^_]*\(_\|$\)/\1/g;x;y/'$(printf "%s" {A..Z} / {a..z})'/;G;:a;s/\(\(^[a-z]\)\|_\([a-z]\)\)\([^\n]*\n\)\(.\)/\5\4/;ta;s/\n//'
AbcDefGhi

Или использовать GNU sed:

echo "ABC_DEF_GHI" | sed 's/\([A-Z]\)\([^_]*\)\(_\|$\)/\1\L\2/g'
AbcDefGhi
0 голосов
/ 27 декабря 2010

Менее страшная версия sed с tr:

эхо ABC_DEF_GHI | sed -e 's / _ // g' - | tr 'A-Z' 'a-z'

0 голосов
/ 27 декабря 2010

Один лайнер с использованием perl:

$ echo 'ABC_DEF_GHI' | perl -npe 's/([A-Z])([^_]+)_?/$1\L$2\E/g;'
AbcDefGhi
0 голосов
/ 27 декабря 2010

Редактировать:

Вот gawk версия:

gawk -F_ '{for (i=1;i<=NF;i++) printf "%s%s",substr($i,1,1),tolower(substr($i,2)); printf "\n"}'

Оригинал:

Использование sed это довольно страшно:

sed -r 'h;s/(^|_)./\n/g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;x;s/((^|_)(.))[^_]*/\3\n/g;G;:a;s/(^.*)([^\n])\n\n(.*)\n([^\n]*)$/\1\n\2\4\3/;ta;s/\n//g'

Здесь это разбито:

# make a copy in hold space
h;
# replace all the characters which will remain upper case with newlines
s/(^|_)./\n/g;
# lowercase all the remaining characters
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;
# swap the copy into pattern space and the lowercase characters into hold space
x;
# discard all but the characters which will remain upper case
s/((^|_)(.))[^_]*/\3\n/g;
# append the lower case characters to the end of pattern space
G;
# top of the loop
:a;
  # shuffle the lower case characters back into their proper positions (see below)
  s/(^.*)([^\n])\n\n(.*)\n([^\n]*)$/\1\n\2\4\3/;
# if a replacement was made, branch to the top of the loop
ta;
# remove all the newlines
s/\n//g

Вот как работает тасование:

Во время запуска, этоВот как выглядит шаблонное пространство:

A
D
G

bc
ef
hi

Перемешивающий цикл выбирает строку, которая находится между последней новой строкой и концом, и перемещает ее в позицию перед двумя последовательными новыми строками (фактически тремя) и перемещает дополнительнуюсимвол новой строки, поэтому перед символом он следовал ранее.

После первого шага в цикле вот как выглядит шаблонное пространство:

A
D

Ghi
bc
ef

И обработка продолжается аналогично, пока ничего не произойдет додополнительная новая строка, в которой совпадение завершается неудачно, а ветвление цикла не берется.

Если вы хотите использовать в качестве заглавия последовательность слов, разделенных пробелами, сценарий будет похож:

$ echo 'BEST MOVIE THIS YEAR' | sed -r 'h;s/(^| )./\n/g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;x;s/((^| ).)[^ ]*/\1\n/g;G;:a;s/(^.*)( [^\n]*)\n\n(.*)\n([^\n]*)$/\1\n\2\4\3/;ta;s/^([^\n]*)(.*)\n([^\n]*)$/\1\3\2/;s/\n//g'
Best Movie This Year
...