Как изменить все строки в файле python от snake_case до camelCase в sed

Я пробовал некоторые sed шаблоны, подобные этому из командной строки

sed -r "s/('[az]+)_([az])([az]+)/\1\U\2\L\3/" 

Но почему-то это не работает. Во-первых, они забыли цифры, которые я могу исправить, но этот шаблон работает только для одного подчеркивания. Так, например, если у меня есть строка в файле

'Foo_bar_foo'

он преобразуется в

'FooBar_foo'

, Что не то, что я хочу (хочу 'fooBarFoo' )

Я хочу только изменить строки в файле, а не имена переменных или что-то еще. Так, например, это

 delta_limits=Limits(general_settings['signal_lower_limit'] 

Должно стать этим

 delta_limits=Limits(general_settings['signalLowerLimit'] 

Если я правильно понимаю, вы хотите изменить _x на X если это происходит внутри строк '...' .

Затем с помощью GNU sed вы можете сделать следующее:

 sed -E ":1;s/^(([^']|'[^']*')*'[^']*)_([^'])/\1\u\3/;t1" 

Это заменяет _X следующим '... сам, следуя последовательности не кавычек или совпадающих кавычек.

Что на входе вроде:

 foo_bar 'ab_cd_ef gh_ij' zz_zz 'aa_bb'' delta_limits=Limits(general_settings['signal_lower_limit'] 

дает:

 foo_bar 'abCdEf ghIj' zz_zz 'aaBb' delta_limits=Limits(general_settings['signalLowerLimit'] 

Это предполагает, что у вас нет строк, вставляющих одинарные кавычки (как в 'foo\'bar' ). Если это так, вам нужно будет учитывать эти экраны с помощью:

 sed -E ":1;s/^(([^']|'([^\']|\\\\.)*')*'([^\']|\\\\.)*)_([^'])/\1\u\5/;t1" 

(также учитывается 'foo\\' ).

Это все еще не охватывает "foo'bar" или строки с обратной косой чертой или « python's '''it's a multi-line quote''' . Вам понадобится парсер python который сможет охватить все случаи.

Для вашего конкретного случая,

 sed -E ":1;s/('\w*)_(\w)/\1\u\2/g;t1" 

Также может быть достаточно (заменяет только _X который следует '\w* ). Это эквивалент GNU sed (за исключением того, что точно соответствует \w ) подхода Glenn perl .

Я бы использовал perl для этого:

 perl -pe "1 while s/('\w+)_([^']*)/\$1\\u\$2/" <<END my_variable = 'a_string_with_snake_case_inside' delta_llimits=Limits(general_settings['signal_lower_limit'] END 
 my_variable = 'aStringWithSnakeCaseInside' delta_limits=Limits(general_settings['signalLowerLimit'] 

Это означает: пока поиск и замена продолжают находить совпадение «1» (нет-op, который возвращает true)