Como alterar todas as strings no arquivo python de snake_case para camelCase em sed

5

Eu tentei alguns padrões sed como este de commandlinefu

sed -r "s/('[a-z]+)_([a-z])([a-z]+)/\U\L/"

Mas de alguma forma não está funcionando. Por um lado, eles esqueceram os dígitos, que eu posso consertar, mas esse padrão funciona apenas para um sublinhado. Então, por exemplo, se eu tiver uma string no arquivo

'foo_bar_foo'

converterá para

'fooBar_foo'

Qual não é o que eu quero (eu quero 'fooBarFoo' )

Eu só quero alterar as strings no arquivo, não os nomes das variáveis ou qualquer outra coisa. Então, por exemplo, isso

delta_limits=Limits(general_settings['signal_lower_limit']

Deve se tornar isso

delta_limits=Limits(general_settings['signalLowerLimit']
    
por user1685095 31.08.2015 / 15:22

2 respostas

6

Se eu entendi corretamente, você deseja alterar _x para X , contanto que ocorra dentro de '...' strings.

Então, com o GNU sed , você poderia fazer:

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

Isso substitui um _X após '... em si seguindo uma sequência de cotações não cotadas ou correspondentes.

Que em uma entrada como:

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

dá:

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

Isso pressupõe que você não tenha sequências que incorporem aspas simples (como em 'foo\'bar' ). Em caso afirmativo, você precisa contabilizar os \' escapes com:

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

(também é responsável por 'foo\' ).

Isso ainda não cobre as citações de "foo'bar" ou as linhas continuadas com barra invertida ou python's '''it's a multi-line quote''' . Você precisaria de um python parser para poder cobrir todos os casos.

Para o seu caso particular,

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

Também pode ser suficiente (apenas substitui o _X que segue '\w* ). Esse é o equivalente em sed do GNU (exceto para o que coincide exatamente com \w ) da abordagem perl de Glenn .

    
por 31.08.2015 / 15:37
2

Eu usaria o perl para isso:

perl -pe "1 while s/('\w+)_([^']*)/\\u\/" <<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']

Isso significa que: enquanto a pesquisa e a substituição continuam a encontrar uma correspondência, "1" (uma não-operação que retorna true)

    
por 31.08.2015 / 15:40