Palavra de pesquisa precedida por Name in Sed

1

Este tópico é motivado pelo comando aritmético encontrado no link deste tópico aqui em Sed. Então eu gostaria de fazer aritmética reversa em Sed.

Dados

Mikael symptom
David symptom
hello symptom

O comando deve retornar as duas primeiras entradas. Look-behind em Perl é uma abordagem, mas eu gostaria de ver se isso pode ser feito com Sed.

Uma abordagem no pseudocódigo

  • Nomes de correspondência: palavras em g/[A-Z]\w\w/ ; %código%

Look-behind

  • Corresponde is.words[2]('symptom') ; lookbehind Nome. Devolva se Nome.

Você pode fazer esse pseudocódigo em Sed?

    
por Léo Léopold Hertz 준영 11.06.2015 / 22:21

3 respostas

1
sed '/^[[:upper:]][[:lower:]]\{1,\} symptom$/!d
    H;x;/^\n/!q;s///;x;d'

Isso irá procurar por linhas que começam com um caractere maiúsculo seguido por um ou mais caracteres minúsculos, em seguida, apenas um < espaço > e a seqüência sintoma . Se a linha atual não corresponder, ela será d eleted e o script iniciará novamente a partir do topo com a próxima linha de entrada.

Se ele corresponder , ele será copiado para H old space após um delimitador de \n ewline inserido. A primeira vez que isso acontecer, h old space estará vazio - e, portanto, o caractere principal será um \n ewline. Depois que a linha correspondente for H eld, os espaços h old e padrão serão e x alterados. Se houver ! não uma entrelinha \n no espaço padrão nesse momento, então sed q uits entrada - abruptamente deixando de ler mais alguma entrada (ou executar qualquer mais comandos em seu script - como d ) . Mas quando houver o primeiro \n ewline é removido e h old e espaços padrão são novamente e x alterados e o espaço padrão é d eleted.

O resultado é o primeiro em que a linha é encontrada e seu marcador de primeira ocorrência significa que ele foi salvo da entrada q user, mas a hora em que ele ocorre termina o processamento.

Mas talvez eu tenha entendido errado? Eu entendi que você quer dizer que você queria apenas as duas primeiras partidas em um arquivo.

Se você quiser apenas o Nome se sintoma $ for fácil:

sed -n '/^[[:upper:]][[:lower:]]\{1,\} [^ ]*$/s/ symptom$//p'

Aqui, apenas verificamos que estamos analisando uma linha de correspondência provável antes mesmo de tentar uma s/// ubstitution - porque a s/// ubstitution é uma função do endereço pai. Se for verdade, tentamos cortar o caminho indesejado e apenas p rint se for bem-sucedido - então as condições both head e tail of line são verificadas antes de nós.

    
por 11.06.2015 / 23:52
1

Pelo que entendi, você deseja imprimir qualquer linha que contenha uma palavra em maiúscula imediatamente seguida pela palavra symptom . Nesse caso:

$ sed -rn '/\b[[:upper:]][[:lower:]]*[[:space:]]+symptom/p' data
Mikael symptom
David symptom

Por conveniência, usei \b , que significa limite de palavra. Isso é pelo menos suportado pelo GNU sed. Deixe-me saber se o seu sed não suporta.

Como funciona:

A forma básica é:

sed -n '/pattern/p' file

Isso imprime apenas as linhas que correspondem a pattern . No nosso caso, o padrão consiste em:

  • \b

    Isso corresponde apenas a um limite de palavras.

  • [[:upper:]][[:lower:]]*

    Corresponde a uma letra maiúscula seguida de zero ou mais letras minúsculas.

    Observe que, antigamente, isso pode ter sido escrito [A-Z][a-z]+ . Por causa do unicode, isso agora não é confiável. O acima usa as classes de caracteres upper e lower e, consequentemente, é seguro para unicode.

  • [[:space:]]+symptom

    Corresponde a um ou mais espaços seguidos pela palavra symptom .

Alternativa

Suponha que você queira imprimir apenas os nomes que precedem symptom :

$ sed -rn 's/\b([[:upper:]][[:lower:]]*)[[:space:]]+symptom.*//p' data
Mikael
David
    
por 11.06.2015 / 22:58
1
sed -n '/^[[:upper:]]\w* symptom/s/ .*//p'

imprimir linhas que começam com a palavra em maiúscula com symptom depois e tudo exceto a palavra "punho" removida.

    
por 12.06.2015 / 00:54