Por que 'awk' / ^ [^ \ t] / {a ++} END {print a} '' não conta as linhas vazias?

5

Por que o awk '/^[^\t]/{a++}END{print a}' não conta as linhas vazias (isto é, linhas que possuem apenas um novo caractere de linha)? Uma linha vazia não é iniciada não com a guia \t ?

    
por Tim 07.01.2018 / 19:53

4 respostas

21

Procurar por algo que não seja X não é o mesmo que procurar por linhas que não contenham X.

Se quisermos encontrar linhas que começam com uma guia, podemos usar o regex /^\t/ . Para encontrar o oposto, isto é, linhas que não começam com uma tabulação, é provavelmente mais simples colocar a negação em torno do padrão inteiro (em vez de em uma classe de caractere):

awk '!/^\t/ {a++} END {print a+0}' 

a+0 para que uma contagem de zero seja zero, em vez de vazia.

Por outro lado, a expressão regular [^\t] requer algum caractere, mas não pode ser uma guia.

Se você deseja corresponder linhas vazias, então /^$/ ou $0 == "" . Ou para combinar linhas ou linhas vazias com apenas espaço em branco /^[[:space:]]*$/ .

    
por 07.01.2018 / 20:15
20

O motivo é que [^\t] requer um caractere. A nova linha ( $ ) não conta como caractere. Você precisa disso:

awk '/^([^\t]|$)/{a++}END{print a}'
    
por 07.01.2018 / 20:01
18

Na regex, [^\t] não significa "corresponder onde não há \t ". Isso significa "corresponder qualquer caractere, exceto \t ". A diferença crítica é que tem que haver um personagem para combinar. No caso de uma linha vazia, não há uma.

    
por 07.01.2018 / 20:01
1

Eu li a expressão correspondente / ^ [^ \ t] / como dizendo "linhas que não começam com uma aba". Se você está procurando linhas verdadeiramente vazias, isso deve funcionar:

awk '/^$/{a +=1;};END{print a;}' /your/file/goes/here

O '^' significa o começo da linha, e '$' significa o fim da linha, então colocá-los juntos significa que não há nada entre o começo e o fim. Eu não verifiquei como isso se comportaria em uma linha delimitada por CR-LF.

    
por 08.01.2018 / 21:44