Várias linhas Localizar e substituir - Notepad ++, regex, copiar um texto de uma linha específica e substituir em outra linha

0

Estou enfrentando uma tarefa hercúlea em localizar e substituir multilinhas (explicadas em partes separadas).

A solução que eu procuro envolve o uso do regex no Notepad ++ com o Find & Substitua ou com o diálogo de busca e substituição de múltiplas linhas disponibilizado pelo plugin NPPtoolbucket .

Este é um extrato de exemplo do arquivo de entrada:

ALPHA('Hello John')
IGNORE111
IGNORE222
BETA('Hi Mary') 

Eu preciso substituir o Hi Mary (quarta linha) por Hello John (conteúdo obtido da primeira linha). Ou seja, o conteúdo real na quarta linha entre BETA ('e') deve ser substituído pelo conteúdo buscado entre ALPHA ('e') da primeira linha.

O resultado desejado deve ser:

ALPHA('Hello John')
IGNORE111
IGNORE222
BETA('Hello John')

O problema que estou enfrentando é que tenho 47 arquivos IFC com (mais de 12.000 linhas cada). Esses arquivos têm um nome de montagem na primeira linha (exclusivo para cada arquivo IFC) e precisam ser usados para substituir o conteúdo em algum lugar nas linhas 48, 87 e muitas outras linhas em todos os 47 arquivos IFC. Tudo segue um padrão particular. Você pode sugerir algum truque para conseguir isso usando o regex?

Diga como - encontre usando (ALPHA\(')(.*)(')(NEW_SYNTAX_I_SEEKING)(BETA\(')(.*)(')

e substitua por

onde

(ALPHA\(') voltará a ser ref ref

(.*) se tornará de volta ref , ele será dividido como - > Olá John

(') voltará a ser ref ref

(NEW_SYNTAX_I'M_SEEKING) ficará de volta ref ; essa será a nova sintaxe de regex que estou procurando, que buscará o conteúdo distribuído em várias linhas e a que não quero alterar

(BETA\(') voltará a ser ref ref

(.*) se tornará de volta ref , ele será dividido como - > Oi Maria, então podemos usar de volta ref \ 2 para substituir de volta ref .

(') voltará a ser ref ref

Espero ter recebido minha pergunta & intenção articulada corretamente. Eu aprecio muito qualquer ajuda dada.

Felicidades, JJ

    
por user705628 10.03.2017 / 11:58

2 respostas

0

A seguinte resposta foi editada - Como é aconselhável usar $ em vez de \ quando tivermos mais de 9 referências de volta

Um pouco de ajustes com informações coletadas em fóruns me ajudaram.

A solução é bem simples (O truque está no passo 2)

1) Abrir incorporado em Localizar & Substitua no notepad ++

2) verifique se você:

[]. corresponde à opção de nova linha

3) Em encontrar o que, digite

(ALPHA \ (') (. *) (' \)) (. *) (BETA \ (') (. *) ('))

Nota - os espaços são dados acima para maior clareza. Não há espaços de todo e deve ser removido

4) Em substituir por, digite

$ 1 $ 2 $ 3 $ 4 $ 5 $$ 2 $ 7

5) clique em "substituir" / "substituir todos" / "substituir todos em todos os documentos abertos" de acordo com suas necessidades.

Bingo!

Explicação

(ALPHA \ (') voltará a ser ref $ 1

(. *) voltará a ser ref $ 2, será dividido como - > Olá John

('\)) voltará a ser ref $ 3

(. *) voltará a ser ref $ 4; Isso vai buscar o conteúdo espalhado por várias linhas e o que eu não quero mudar

(BETA \ (') voltará a ser ref $ 5

(. *) voltará a ser ref $ 6, será dividido como - > Oi Mary, então podemos usar de volta $ 2 para substituir de volta $ 6.

('\)) voltará a ser ref $ 7

    
por 11.03.2017 / 11:47
0

Se você trabalha muito com arquivos de texto, vai adorar o awk .

awk -i inplace 'NR==1 && match($0, /.*\('\''(.+)'\''\)/,matches) {name = matches[1]; print $0} /IGNORE/ {print $0} NR>1 && !/IGNORE/ {print gensub (/([\w ]*\('\'').+('\''\))/, "\1"name"\2", "1")}' *.txt

A explicação vai demorar um pouco, deixe-me primeiro dividir o comando em três seções, cada uma composta de uma condição e um comando:

  • NR==1 && match($0, /.*\('\''(.+)'\''\)/,matches) {name = matches[1]; print $0} isto imprime a primeira linha e copia o que no seu caso é o nome do conjunto para uma variável simplesmente chamada name .
  • /IGNORE/ {print $0} se as linhas corresponderem ao texto IGNORE , basta imprimi-las.
  • NR>1 && !/IGNORE/ {print gensub (/([\w ]*\('\'').+('\''\))/, "\1"name"\2", "1")} executa a regex e substitui as linhas restantes, empregando a variável name criada anteriormente.

Mais alguns detalhes a seguir:

awk esta é uma ferramenta para manipular arquivos de texto; alternativamente, eu recomendaria perl .

-i inplace significa que os arquivos originais serão editados (faça backups!). Aviso de isenção de responsabilidade: Eu não consegui testar essa configuração ainda porque ela requer uma versão awk mais recente do que a que eu instalei.

' o comando é uma string, portanto é encapsulado em apóstrofos.

NR==1 esta é uma condição, o número da linha deve ser 1 .

&& , isso significa AND.

match( esta é outra condição que deve ser satisfeita: uma função de correspondência regexp que leva 3 argumentos.

$0 primeiro argumento: isso representa a linha inteira.

/.*\('\''(.+)'\''\)/ second argumento, a expressão regular

matches terceiro argumento, a variável onde as sequências correspondentes devem ser armazenadas.

{ here inicia as ações que devem ser executadas caso as condições sejam verdadeiras.

name = matches[1] a variável name é criada e é designada para ser igual ao primeiro grupo de captura (o mesmo que backreference ).

; o ponto-e-vírgula separa as instruções.

print $0 também imprimimos a primeira linha.

/IGNORE/ procura linhas que contenham o texto IGNORE .

{print $0} apenas imprima-os.

NR>1 && !/IGNORE/ condition: para todas as linhas, exceto a primeira, se elas não contiverem o texto IGNORE .

{print imprime o resultado da substituição. gensub ( function que realiza pesquisa e substituição permitindo o uso de backreferences.

/([\w ]*\('\'').+('\''\))/ do padrão de pesquisa. Aqui a seqüência '\'' é o que é necessário para inserir um único ' .

"\1"name"\2" o padrão de substituição. "" e "" são duas referências anteriores.

"1" significa que apenas a primeira correspondência deve ser substituída.

' end do comando awk .

*.txt run awk em todos os arquivos com extensão .txt no diretório atual.

Observação: sei que você está perguntando como fazer isso no Notepad ++, mas acredito que deva considerar as ferramentas de linha de comando. A razão é que os programas gráficos são mais aptos a executar uma operação única, mas no comentário que você especifica, você gostaria de automatizar o trabalho e processar 47 arquivos de uma só vez. A linha de comando é mais apta à automação do que às interfaces gráficas, esse é o meu ponto.

Para começar, você tem gawk (GNU awk) para Windows e, se quiser continuar, pode trabalhar no Linux ou instalar um ambiente semelhante ao Linux, como o Cygwin .

    
por 10.03.2017 / 17:21