Continuo lendo a sed
documentação e muitas postagens, mas não consigo entender isso. Eu tenho um grande número de arquivos Java. Nesses arquivos há chamadas para um método que converte a enumeração em um número inteiro usando o toInt()
método. Quero examinar todos os arquivos e me livrar .toInt()
de uma enumeração específica.
É isso que eu quero. As sequências de código originais:
foo(ENUM_NAME.ENUM_VALUE.toInt(), arg2, arg3)
foo(ENUM_NAME.ENUM_VALUE2.toInt(), arg2, arg3)
Eu quero terminar com:
foo(ENUM_NAME.ENUM_VALUE, arg2, arg3)
foo(ENUM_NAME.ENUM_VALUE2, arg2, arg3)
ENUM_VALUE
podem haver centenas de possibilidades diferentes, então não consigo codificar. Parece que há alguma confusão sobre o que precisa ser mudado, então tentarei ser mais claro.
Há uma enumeração chamada TRANF_FIELD
em meus arquivos Java. Os valores disponíveis para essa enumeração podem ser um entre dois mil valores, seguidos por .toInt()
. Eu preciso me livrar do .toInt()
. Os nomes das funções são todos irrelevantes.
A seguir estão exemplos de construções de código intercaladas em meu código Java e como elas devem ser processadas:
TRANF_FIELD.TRANF_VALUE_1.toInt()
Quero o.toInt()
deletado, deixandoTRANF_FIELD.TRANF_VALUE_1
sobra.
TRANF_FIELD.TRANF_KILL_ME.toInt()
Quero que.toInt()
seja deletado, deixandoTRANF_FIELD.TRANF_KILL_ME
TRANG_FIELD.TRANG_VALUE_1.toInt()
Sem alteração, pois não éTRANF_FIELD
.
TRANF_FIELD.TRANF_VALUE_1.length()
Nenhuma mudança, porque não é.toInt()
.
Responder1
Você parece querer alterar todas as ocorrências de
TRANF_FIELD.some_enum_value.toInt()
para
TRANF_FIELD.that_enum_value
deixando outras enumerações (por exemplo, TRANG_FIELD.TRANG_VALUE.toInt()
) e outros métodos (por exemplo, TRANF_FIELD.TRANF_VALUE.length()
) sozinhos. Isto parece simples:
sed 's/\(TRANF_FIELD\.[A-Za-z0-9_]*\)\.toInt()/\1/'
onde
[A-Za-z0-9_]*
é qualquer número de caracteres alfanuméricos (incluindo sublinhados). O objetivo é corresponder a qualquer valor de enumeração válido. Na verdade,[A-Za-z_][A-Za-z0-9_]*
seria melhor, porque[A-Za-z0-9_]*
poderia corresponder a uma string vazia ou começando com um dígito.\(
…\)
agrupa o nome da enumeração (TRANF_FIELD
), o ponto literal (\.
) e o valor da enumeração (do primeiro marcador).\1
significa “substituir a string completa que você encontrou pelo primeiro grupo”, ou seja, descartar a.toInt()
parte.- Para lidar com múltiplas ocorrências por linha, adicione
g
(global) após a última barra. - Isso não irá lidar com espaços em branco incorporados, por exemplo,
TRANF_FIELD . TRANF_VALUE
. Corrigir isso é deixado como um exercício. Isso não tratará expressões quebradas entre linhas; por exemplo,
i = TRANF_FIELD .TRANF_VALUE.toInt();
Isso é mais difícil de consertar.
Responder2
Obrigado por toda a sua ajuda, pessoal. Adicionei o -i de uma resposta, incluindo o caminho para todos os arquivos java, ao que G-man sugeriu e funcionou. Se vocês estiverem em Long Island, eu pago uma cerveja para vocês. Isso me economizou muito tempo.
sed -i 's/\(TRANF_FIELD\.[A-Za-z0-9_]*\)\.toInt()/\1/g'
Responder3
Dependendo do seu sistema operacional, um inline ( -i
) sed
poderia fazer isso:
sed -i 's:\.toInt()::' filename
Onde apenas substituirá a instância de ".toInt()" por "" - o .
é escapado para que não atue como um curinga.
Ao mencionar vários arquivos, você terá que repetir este comando procurando por todos os arquivos no diretório e subdiretórios atuais:
find . -type f -exec sed -i 's:\.toInt()::' {} \;
No entanto, ocorrerá um erro se os nomes dos arquivos contiverem espaços, então podemos usar o xargs
comando para lidar com isso, que colocará aspas em todos os nomes de arquivos:
find . -type f | xargs -I{} sed -i 's:\.toInt()::' "{}"
No entanto, isso também selecionará arquivos compilados, portanto, para evitá-los, podemos usar um recurso útil perl
para ignorá-los:
find . -type f | perl -nle 'print if -T' | xargs -I{} sed -i 's:\.toInt()::' "{}"
Responder4
sed 's/ENUM_NAME\.\(.*\)\.toInt()/ENUM_NAME.\1/g'