Como extrair texto usando sed

3

Eu tenho um arquivo de texto e quero extrair apenas o texto que começa e termina com certas strings usando sed .

Por exemplo, na linha:

string>![TEST[Extract this string]>/string>

Eu quero pegar

Extract this string 

Como você implementaria isso com sed ? Basicamente eu quero pegar o texto que começa com a expressão " string>![TEST[ " e terminar com a expressão " ]>/string> ".

    
por Vivek 07.03.2015 / 20:11

5 respostas

6

sed -e 's/string>!\[TEST\[\(.*\)]>\/string>//' file

ou

sed -e 's|string>!\[TEST\[\(.*\)]>/string>||' file

Saída:

Extract this string
    
por 07.03.2015 / 20:18
4

Você precisa dizer à string não apenas o que corresponde, mas também o que salvar:

sed -ne 's@string>!\[TEST\[\([^]]*\)\]>/string>@@gp'

O comando s em sed recebe dois argumentos: uma expressão regular e uma string de substituição. Normalmente, o delimitador / é usado para separar os dois, mas você pode usar qualquer caractere, neste caso @ . Existem alguns caracteres especiais nas expressões regulares, como [ , ] . Eles precisariam ser citados com \ se você quiser o caractere real, por exemplo, %código%. O string>!\[ captura tudo entre os colchetes. E o \([^]]*\) substitui a string who pelo que corresponde à expressão regular. No final está , que diz ao enviar para coincidir várias vezes na linha ( @gp ) e imprimir a linha substituída (depois que dissermos g para não imprimir linhas com a opção sed .

    
por 07.03.2015 / 20:24
4

Uma abordagem simples com o Awk:

awk -F'[][]' '{print $3}' file
    
por 07.03.2015 / 20:26
2
sed '/\n/P;//D;y|]|\n|
    s|\n>/string>|]|
    y|[]\n|\n[]|
    s|string>!\nTEST\n\(.*\[\)|[|
    y|\n[|[\n|;D' <<\IN
    string>![TEST[][]Extract[ ]this[ ]string[][]>/string>
IN

Talvez você possa especificar que os colchetes são delimitadores aceitáveis aqui, mas, em caso afirmativo, parece estranho que os delimitadores finais sejam tão elaborados nesse caso. E de qualquer forma, como a questão apenas afirma que você precisa obter texto entre string>![TEST[ e ]>/string> e é isso que isso tenta fazer - embora falhe se texto deve abranger os limites da nova linha.I

De qualquer forma, funciona por:

  1. y|]|\n| - Primeiro, traduz todas as ocorrências de ] em uma linha para um \n ewline.
  2. s|\n>/string>|]| - Ele substitui o primeiro \n ewline que é seguido imediatamente pelo seu delimitador direito com ] (o que torna o único ] possível em uma linha naquele momento)
  3. y|[]\n|\n[]| - Se a última substituição foi bem-sucedida, um ] é traduzido para [ , enquanto todos os \n ewlines são convertidos de volta para ] e todos [ são traduzidos simultaneamente para \n ewlines. três tipos de personagens são deslocados, basicamente.
  4. s|string>!\nTEST\n\(.*\[\)|[| - Se o delimitador de extremidade esquerda for encontrado antes de um [ nesse momento, deve ser que ambas as extremidades da primeira ocorrência de texto tenham sido encontradas. Essa correspondência é substituída por [ .
  5. y|\n[|[\n| - E assim, na última tradução, se houver qualquer [ em uma linha, elas se tornarão novas linhas e todas as novas linhas se tornarão [ .

Neste ponto, tudo até a primeira linha de ocorrência (ou a linha inteira, se não houver nenhuma) é D eleted. Se alguma coisa permanece, é enviado para o topo do script. Se a iteração anterior resultou em dois \n ewlines no espaço padrão - ambas as extremidades do texto delimitado, ele será P rinted para a primeira \n ewline. Caso contrário, o espaço de padrão já testado é limpo e o ciclo continua.

E assim o exemplo acima imprime:

][]Extract[ ]this[ ]string[][

... e ele imprimirá cada um em uma linha separada, como muitas strings delimitadas de forma semelhante, que podem ser totalmente delimitadas por linha, à esquerda e à direita, ou nada.

    
por 07.03.2015 / 20:43
1

Através do GNU grep ,

$ echo 'string>![TEST[Extract this string]>/string> foo bar string>![TEST[Extract this string]>/string>' | grep -oP 'string>!\[TEST\[\K.*?(?=]>/string>)'
Extract this string
Extract this string
    
por 08.03.2015 / 05:45