comando unix per verificare l'intervallo di parole nel testo


3

Quali comandi unix posso usare per determinare l'intervallo di righe in cui una parola appare nel testo? Lo "span" è uguale al numero di riga dell'ultima istanza di una parola meno il numero di riga della prima istanza della parola.

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

Nell'esempio sopra, lo "span" di "unix" sarebbe 2 (3-1).

Finora ho cercato di usare grep -n ma non credo che grep sia abbastanza potente. Forse qualche uso di sed o awk?

Grazie!


1
Althoug ho già risposto. Il spansarà 2, perché ci sono due linee in cui la parola unix appaiono o perché la parola unix apears due volte nella stessa linea?
Fmanco,

Span = (ultima riga con 'unix' - prima riga con 'unix') quindi perché 'unix' appare sulle righe 1,2,3 (o 0,1,2 se preferisci) 3-1 è uguale a 2 (o di nuovo 2 -0 = 2), quindi lo "span" è 2. Mi dispiace che non sia chiaro.
Ocasta Eshu,

Post modificato per chiarezza.
Ocasta Eshu,

Risposte:


4

utilizzando awk

Comando

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

Come funziona

  • awk '{ COMMANDS } END { FINALCOMMAND }' FILEesegue COMMMANDSper ogni riga di FILE.

    Successivamente, viene eseguito FINALCOMMAND.

  • if($0 ~ /PATTERN/) { ... }controlla se si PATTERNverifica nella riga ( $0).

    Se lo fa, ...viene eseguito.

  • The first time the pattern occurs,PRIMO` sarà vuoto.

    Pertanto, if(!FIRST) FIRST=NRmemorizzerà il numero di riga ( NR) in FIRST.

  • Per ogni occorrenza, LAST=NRmemorizzerà il numero di riga ( NR) in LAST.

    Dopo aver elaborato tutte le occorrenze, LASTconterrà il numero di riga dell'ultima occorrenza.

  • print LAST-FIRST stampa la differenza tra l'ultimo e il primo numero di riga.


Utilizzando solo grep, headetail

copione

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))

Come funziona

  • grep -n PATTERN FILEmostra tutte le righe in FILEcorrispondenza PATTERN, precedute dal loro numero di riga.

  • echo "$MATCHES" | head -n 1mostra la prima riga di MATCHESe grep -Po "^ *\d+"filtra tutto tranne il numero di riga.

    In seguito. [ $FIRST ] || FIRST=0controlla se FIRSTè stato definito. In caso contrario, viene impostato su 0.

  • echo "$MATCHES" | tail -n 1mostra l' ultima riga di MATCHESe grep -Po "^ *\d+"filtra tutto tranne il numero di riga.

    In seguito. [ $LAST ] || LAST=0controlla se LASTè stato definito. In caso contrario, viene impostato su 0.

  • $(($LAST - $FIRST)) calcola la differenza tra l'ultimo e il primo numero di riga.


0

Questo troverà l'intervallo tra la prima e l' ultima occorrenza di una parola (cioè le parole intermedie non sono considerate) ...

Nota: i sedcomandi ie a(inserisci e aggiungi) devono essere l'ultimo comando su una riga.

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

O questo, che collega sed a sed , ma forse è più semplice.

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

0

Questo potrebbe funzionare per te:

sed '/unix/=;d' file | sed '1h;$!d;G;s/\n/-/' | bc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.