Usando o corte para retornar o meio de uma string

1

Eu tenho uma string xml ecoada em stdout ao longo das linhas de

<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>

Eu quero retornar a string {41c33a-4893b-3627a-617a} neste caso. Eu estava pensando em usar o corte (talvez até mesmo canalizá-lo duas vezes), mas não tenho idéia da sintaxe adequada. Estou usando bash.

    
por myol 24.04.2016 / 17:07

4 respostas

2

Você pode usar a opção cut de -d para definir um delimitador (que é excluído dos campos resultantes):

echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | cut -d\> -f2 | cut -d\< -f1

Isso se divide em > e gera o segundo campo, deixando {41c33a-4893b-3627a-617a}</xml:attribute , depois novamente em < e produz o primeiro campo.

Os campos descrevem o texto entre delimitadores e entre o início do texto e o primeiro delimitador e o último delimitador e o final do texto. Usando > no texto original, você acaba com:

  1. <xml:attribute
  2. {41c33a-4893b-3627a-617a}</xml:attribute
  3. a string vazia

(o delimitador é omitido). Então, usando < no campo 2, dá

  1. {41c33a-4893b-3627a-617a}
  2. /xml:attribute

e o campo 1 é o resultado que você está procurando.

    
por 24.04.2016 / 17:12
1

Para manipulações simples de strings, você deve geralmente usar as próprias construções do shell, ligadas a expansão de parâmetros . Os utilitários externos são melhores para processar grandes volumes de texto, mas para uma única string, iniciar uma ferramenta externa é lento e obter a citação correta pode ser difícil.

mystring='<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>'
content="${mystring#*>}"; content="${content%<*}"
braced="${mystring#*\{}"; braced="${braced%%\}*}"; braced="{$braced}"

content é definido como a string original menos as partes% e co -de% iniciais e finais. <…> está definido para a primeira parte que parece com braced .

    
por 24.04.2016 / 22:38
0

Você também pode ter sed extrair o campo especificado por uma expressão regular. Útil se você tiver critérios de correspondência mais complexos:

echo '<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>' | \
sed -E 's/^.+>({.+})<.+$//'
    
por 24.04.2016 / 23:16
0

Ou com awk , usando o regexp <|> como o delimitador de campo:

$ echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | 
       awk -F '<|>' '{print $3}'
{41c33a-4893b-3627a-617a}

Nota: testado com o GNU awk , mawk e original-awk . Funciona da mesma forma em todos os três.

A versão perl é muito semelhante (exceto que perl matrizes são baseadas em zero, e perl print não exibe um \n à direita, a menos que você diga explicitamente):

echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" |
     perl -n -a -F'<|>' -e 'print $F[2],"\n"'

Observe também - isso só funciona de maneira confiável porque é uma única linha de entrada contendo um único fragmento de XML. Expressões regulares não podem ser usadas para analisar de forma confiável o XML real. Use uma ferramenta de análise XML em vez disso, por exemplo, xmlstarlet ou uma das muitas bibliotecas de análise de XML para perl , python e outras linguagens.

    
por 25.04.2016 / 07:11