sed -e 's/string>!\[TEST\[\(.*\)]>\/string>//' file
ou
sed -e 's|string>!\[TEST\[\(.*\)]>/string>||' file
Saída:
Extract this string
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>
".
sed -e 's/string>!\[TEST\[\(.*\)]>\/string>//' file
ou
sed -e 's|string>!\[TEST\[\(.*\)]>/string>||' file
Saída:
Extract this string
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
.
Uma abordagem simples com o Awk:
awk -F'[][]' '{print $3}' file
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:
y|]|\n|
- Primeiro, traduz todas as ocorrências de ]
em uma linha para um \n
ewline. 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) 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. 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 [
. 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.
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
Tags text-processing sed