Contagem de tabulações por linha no arquivo de texto com utils

3

Eu tenho um arquivo tabulado. Gostaria de verificar se cada linha tem o mesmo número de abas.

Para o primeiro passo, gostaria de imprimir o número de separadores para cada linha individual.

Já experimentei grep -o '\t' infile | wc -l , mas a minha implementação de grep diz grep: invalid option -- o . Existe outra maneira?

É bom ter: se possível, devido à preferência pessoal, prefiro fazer isso com ferramentas util (grep, cat, etc.), de preferência não awk ou bash scripting.

    
por n611x007 11.11.2013 / 16:12

4 respostas

6

Se o seu objetivo é apenas detectar se há sempre o mesmo número de guias por linha (no bash, no awk):

sed 's/[^\t]//g' file | sort -u | wc -l

Se a saída for 1, então é bom!

Ou, substituindo sed por tr :

tr -cd \t\n < file | sort -u | wc -l

ou se você gosta de usos inúteis de gatos e não gosta de opções de concatenação:

cat file | tr -c -d \t\n | sort -u | wc -l

O truque é remover todos os caracteres que não são guias em cada linha e, em seguida, ordenar / uniq o que resta.

    
por 11.11.2013 / 17:23
5

Acho que sed etc. não é adequado para isso, uma maneira fácil é chamar awk com tab como separador de campo:

printf $'hello\tworld\thugo\nfoo\tbar\nbaz\n' | awk -F$'\t' '{print NF-1;}'

que dá

2
1
0
    
por 11.11.2013 / 16:50
1

Honestamente, a maneira mais fácil é usar awk :

awk -F'\t' '{print NF-1}' foo

NF é o número de campos, -F'\t' informa awk para dividir campos nas guias, portanto, o número de guias será um a menos que o número de campos, e é por isso que temos awk print NF-1 .

Se você realmente não quer usar awk você poderia fazer ( nota: isso não conta as abas finais no final de cada linha):

$ while read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
2
4
0
1
0

Para lidar com guias iniciais e finais, bem como com outros caracteres estranhos (como barras invertidas), faça isso:

$ while IFS= read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
  • while read lines; do ... ; done < foo : leia cada linha do arquivo foo na variável $line .
  • echo "$line" | fold -1 : o comando fold irá imprimir um caractere por linha
  • grep -c $'\t' : isso é executado em cada linha do arquivo ( $line ), mas desde $line foi dobrado em um caractere por linha, grep -c contará o número de guias nessa linha. Se você não for fold , grep -c contará o número de linhas correspondentes e não fornecerá uma linha de contagem de guias por .

Você também pode usar o Perl, mas acho que não está disponível também. Aqui está um caminho, independentemente:

perl -lne '@a=/\t/g;print scalar @a' foo 
    
por 11.11.2013 / 16:51
0

Eu acho que é tarde demais, mas a linha de comando do OP estava quase certa. Ele só precisava do $ na frente de sua TAB ('\ t')

grep -o $'\t' infile | wc -l

faz exatamente o que ele queria depois.

    
por 28.01.2015 / 19:36