unix comando para verificar a extensão da palavra no texto

3

Que comando (s) unix eu posso usar para determinar o intervalo de linha que uma palavra aparece no texto? O "span" é igual ao número da última instância de uma palavra menos o número da primeira instância da palavra.

1| unix is on two lines
2| once above, and once below
3| unix

No exemplo acima, o "span" de 'unix' seria 2 (3-1).

Até agora eu tenho tentado fazer uso do grep -n, mas eu não acho que o grep seja poderoso o suficiente. Talvez algum uso de sed ou awk?

Obrigado!

    
por Ocasta Eshu 27.06.2012 / 04:14

3 respostas

4

Usando awk

Comando

awk '{ if($0 ~ /PATTERN/) { if(!FIRST) FIRST=NR; LAST=NR } } END { print LAST-FIRST }' FILE

Como funciona

  • awk '{ COMMANDS } END { FINALCOMMAND }' FILE executa COMMMANDS para cada linha de FILE .

    Depois, executa FINALCOMMAND .

  • if($0 ~ /PATTERN/) { ... } verifica se PATTERN ocorre na linha ( $0 ).

    Se isso acontecer, ... será executado.

  • The first time the pattern occurs, FIRST 'estará vazio.

    Portanto, if(!FIRST) FIRST=NR armazenará o número da linha ( NR ) em FIRST .

  • Para cada ocorrência, LAST=NR armazenará o número da linha ( NR ) em LAST .

    Após processar todas as ocorrências, LAST manterá o número da linha da última ocorrência.

  • print LAST-FIRST imprime a diferença entre o número da última e da primeira linha.

Usando apenas grep , head e tail

Script

MATCHES=$(grep -n PATTERN FILE)
FIRST=$(echo "$MATCHES" | head -n 1 | grep -Po "^\d+"); [ $FIRST ] || FIRST=0
LAST=$(echo "$MATCHES" | tail -n 1 | grep -Po "^\d+"); [ $LAST ] || LAST=0
SPAN=$(($LAST - $FIRST))

Como funciona

  • grep -n PATTERN FILE mostra todas as linhas em FILE matching PATTERN , precedidas pelo número da linha delas.

  • echo "$MATCHES" | head -n 1 mostra a linha primeiro de MATCHES e grep -Po "^ *\d+" filtra tudo, exceto o número da linha.

    depois. [ $FIRST ] || FIRST=0 verifica se FIRST foi definido. Caso contrário, fica definido para 0 .

  • echo "$MATCHES" | tail -n 1 mostra a linha última de MATCHES e grep -Po "^ *\d+" filtra tudo, menos o número da linha.

    depois. [ $LAST ] || LAST=0 verifica se LAST foi definido. Caso contrário, fica definido para 0 .

  • $(($LAST - $FIRST)) calcula a diferença entre o número da última e da primeira linha.

por 27.06.2012 / 04:47
0

Isto irá encontrar o intervalo entre a primeira e última ocorrência de uma palavra (ou seja, palavras intermediárias não são consideradas) ...

Nota: Os comandos sed i e a (insert e append) devem ser o último comando em uma linha.

eval "$(sed -ne "1 i b=
                 /\<$word\>/{=; i ;e=
                 =}
                 $ {a ;echo \$((e-b))
                 }
                " "$file" | tr -d '\n')"

Ou este, que canaliza sed para sed , mas talvez seja mais simples.

eval "$(sed -n "/\<$word\>/=" "$file" |
        sed -n '1{i b=
             p};${i;e=
             p;   a;echo \$((e-b))
              }' | tr -d '\n')"   
    
por 27.06.2012 / 06:54
0

Isso pode funcionar para você:

sed '/unix/=;d' file | sed '1h;$!d;G;s/\n/-/' | bc
    
por 04.07.2012 / 20:40