Делайте различные замены, но только перед персонажем - PullRequest
3 голосов
/ 27 сентября 2019

Я делаю что-то вроде этого:

echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/_([[:alnum:]])/\U\1/g'

и получаю в результате:

fooBarBaz=fooBarBaz

Есть ли способ получить fooBarBaz=foo_bar_baz вместо этого?

Я пытался сделать это, не жадный:

echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/([^=].*?)_([[:alnum:]])/\1\U\2/g'

, но результат таков:

foo_bar_baz=foo_barBaz

Мне нужно преобразовать из:

foo_bar_baz=foo_bar_baz

до:

fooBarBaz=foo_bar_baz

Ответы [ 4 ]

5 голосов
/ 27 сентября 2019

РЕДАКТИРОВАТЬ: Добавление большего общего решения, которое будет работать более чем на 3 значения до = тоже.

awk '
BEGIN{
  FS=OFS="="
}
{
  num=split($1,array,"_")
  for(i=2;i<=num;i++){
    val=(val?val:"")toupper(substr(array[i],1,1)) substr(array[i],2)
  }
  $1=array[1] val
  val=""
}
1
'  Input_file


Это должно быть простой задачей для awk.

echo 'foo_bar_baz=foo_bar_baz' | awk '
BEGIN{
  FS=OFS="="
}
{
  split($1,array,"_")
  $1=array[1] toupper(substr(array[2],1,1)) substr(array[2],2) toupper(substr(array[3],1,1)) substr(array[3],2)
}
1'


Чтобы просто удалить _ при первом использовании (это не сделает заглавной буквы):

echo 'foo_bar_baz=foo_bar_baz' | awk 'BEGIN{FS=OFS="="}{gsub(/_/,"",$1)} 1'
2 голосов
/ 28 сентября 2019

С GNU awk для соответствия 3-го аргумента ():

$ echo 'foo_bar_baz=foo_bar_baz' |
  awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
fooBarBaz=foo_bar_baz

Обратите внимание, что вышеприведенное решение не ограничено каким-либо конкретным числом _ с или какой-либо конкретной буквой после символов подчеркивания:

$ echo 'wee_sleekit_cowrin_timrous_beastie=foo_bar_baz' |
  awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
weeSleekitCowrinTimrousBeastie=foo_bar_baz

Измените _(.) на _([[:lower:]]), если вы хотите, чтобы подчеркивание было удалено только после буквы нижнего регистра.

2 голосов
/ 28 сентября 2019

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

sed -E 'h;s/_(.)/\u\1/g;G;s/=.*=/=/' file

Сделать копию текущей строки.Удалите все символы _ и заглавные буквы следующих символов.Добавьте копию и замените все, что находится между =, одним =.

Альтернатива:

sed -E ':a;s/_(.*=)/\u\1/;ta' file 
1 голос
/ 28 сентября 2019

Вы можете использовать

s='foo_bar_baz=foo_bar_baz'
sed -E ':a;s/^([^=_]*)_([[:alnum:]])/\1\U\2/g; ta' <<< "$s"
# => fooBarBaz=foo_bar_baz

См. онлайн sed демо

Подробнее

  • :a - определить метку a для перехода в случае успешного замещения
  • s/^([^=_]*)_([[:alnum:]])/\1\U\2/g - найти
    • ^ - начало строки
    • ([^=_]*) - группа 1 (\1 в шаблоне замены): любые 0+ символов, кроме = и _
    • _ - подчеркивание
    • ([[:alnum:]]) -Группа 2 (\2 в шаблоне замены): буквенно-цифровой символ
    • \1\U\2 - значение группы 1 и затем значение группы 2 в верхнем регистре
  • ta- t - это команда ветвления, заставляющая sed вернуться к метке a и повторить сопоставление.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...