Pesquisar e substituir pergunta

2

Eu preciso encontrar todas as ocorrências de AAsomeArbitraryStringBB e substituí-las por CCsomeArbitraryStringDD .

Então

AAHelloBB
Text
AAByeByeBB

torna-se

CCHelloDD
Text
CCByeByeDD.

É importante observar que a string de substituição contém parte da string de pesquisa.

    
por User133713 12.01.2015 / 20:24

2 respostas

2

Esta é uma tarefa básica para o comando sed :

sed 's/AA\(someArbitraryString\)BB/CCDD/g'

Eventualmente, se você quiser fazer isso para todas as "strings arbitrárias":

sed 's/AA\(.*\)BB/CCDD/g'
    
por 12.01.2015 / 20:29
2
sed "s/\([AB]\)*/\n&\n/g
     s/AA\n\([[:alnum:]]\{1,\}\)\nBB/CCDD/g
     s/\n//g
" <<\INPUT
AAHelloBB Text AAByeByeBB
INPUT

Acho que só deve fazer a substituição AA>>CC&&BB>>DD se houver 1 ou mais caracteres alfanuméricos [s] entre os dois grupos e sempre espremer as ocorrências possíveis tão próximas umas das outras quanto possível.

O exemplo imprime:

CCHelloDD Text CCByeByeDD

A parte mais difícil disso é na primeira instrução s/// ubstitution. Ele coloca um caractere de% ewline \n na cabeça e cauda de todas as ocorrências AAA* e BBB* no espaço padrão simultaneamente. A delimitação pode ser difícil às vezes - muitas vezes, colocar um delimitador head-end pode mudar onde um delimitador final deve ir ou vice-versa. Eu tento dar esse passo em um único limite sempre que possível para evitar ter que editar uma edição.

Então, vamos ver de dentro para fora, mas consideramos que sed está varrendo o espaço padrão da esquerda para a direita para cada ocorrência do padrão resultante, porque eu coloco o sinalizador g lobal no cauda da declaração s/// ubstitution.

  • [AB] - sed irá pausar sua varredura quando encontrar o primeiro A ou B em qualquer série de como ele varre. Em seguida, procurará por ...
  • \([AB]\)* - pelo menos um caractere idêntico imediatamente subseqüente e quaisquer / todos os caracteres idênticos contínuos pelo tempo que a sequência puder durar. Eu agrupo a classe de caractere [AB] em uma \( sub-expressão \) e assim posso me referir ao seu conteúdo com a referência de retorno .
    • Isso é diferente de fazer [AB]\{2,\} ou mesmo \([AB]\)\{2,\} , já que nesses casos sed considerará A e B para corresponder ao padrão. Em vez disso, todos os caracteres adicionados ao grupo de correspondências são idênticos à primeira correspondência em [AB] .
  • \n&\n - no lado direito da s/// ubstitution eu referenciei toda a sequência que combinava com & e inseria em sua cabeça e seguia um caractere \n ewline.
    • Muitos sed s não suportarão uma escape de barra invertida \n ewline no lado direito de uma substituição. Se esse for o seu caso, você pode simplesmente usar um caractere literal \n ewline no lugar do n .

Aqui está um l ook nos resultados dessa s/// ubstitution na string de entrada de exemplo:

\nAA\nHello\nBB\n Text \nAA\nByeBye\nBB\n

Você pode ver isso além de inserir caracteres% w /% ewline extras (que é praticamente o único caractere que só pode ocorrer em um espaço de padrão \n como resultado de uma edição) sed não alterou a string - nenhum caractere de entrada foi modificado.

Você também pode ver que cada seqüência sed ou AAA* agora está imediatamente dentro de BBB* ewlines. Então, quando eu fizer o próximo \n lobal g ubstitution eu só tenho que dizer s/// para ...

  • sed - inicia cada correspondência apenas no final de uma sequência AA\n imediatamente seguida por ...
  • AAA* - um ou mais caracteres alfanuméricos. Isso nunca deve funcionar como uma sequência \([[:alnum:]]\{1,\}\) , porque onde BBB* precede imediatamente AAA* , há agora dois intermediários BBB* ewlines entre eles. Esta seqüência alfanumérica deve ser imediatamente seguida por ...
  • \n - o fim da cabeça de uma sequência \nBB .

E no lado direito ...

  • BBB* - substituímos CCDD w / AA\n CC por si e w / \nBB .

Neste momento, um DD ook revela ...

\nCCHelloDD\n Text \nCCByeByeDD\n

... sucesso aparente! Agora precisamos apenas fazer ...

's/\n//g'

... e remova todos os delimitadores de ewline l restantes e o trabalho está concluído.

Aqui está o resultado do meu martelar aleatoriamente no teclado por alguns segundos renderizados como entrada. É um exemplo de entrada muito mais complicado, então eu o divido com escape \n ewlines em um documento aqui. O shell removerá todas as novas linhas que você pode ver aqui antes de passar o resultado de linha única para \n como entrada:

sed ... <<IN
AA  kj \
BB\
AAAAAABAkl\
AAAAasjd\
AAAAfo\
BB\
AAia\
BBsdfjomAl\
BBks\
BBmdlmdsviom\
BB\
AAiodsvgmnoi
IN

... e sed ook após o primeiro l ubstitution:

\nAA\n kj \nBB\n\nAAAAAA\nBAkl\nAAAA\nasjd\nAAAA\nfo\nBB\n\nAA\nia\nBB\nsdfjomAl\nBB\nks\nBB\nmdlmdsviom\nBB\n\nAA\niodsvgmnoi

... e seguindo o segundo ...

\nAA\n kj \nBB\n\nAAAAAA\nBAkl\nAAAA\nasjd\nAACCfoDD\n\nCCiaDD\nsdfjomAl\nBB\nks\nBB\nmdlmdsviom\nBB\n\nAA\niodsvgmnoi

... e o produto final ...

AA kj BBAAAAAABAklAAAAasjdAACCfoDDCCiaDDsdfjomAlBBksBBmdlmdsviomBBAAiodsvgmnoi
    
por 12.01.2015 / 21:41