Cuente las tabs por línea en el file de text con utils

Tengo un file tabulado. Me gustaría comprobar si cada línea tiene el mismo número de tabs.

Para el primer paso, me gustaría imprimir el número de tabs para cada línea individual.

He intentado grep -o '\t' infile | wc -l grep -o '\t' infile | wc -l , pero mi implementación de grep dice grep: invalid option -- o . ¿Hay otra manera?


Es bueno tener: si es posible, debido a las preferences personales, preferiría hacer esto con herramientas de utilidad (grep, cat, etc.), preferiblemente no con awk o bash scripting.

Si su objective es solo detectar si siempre hay el mismo número de tabs por línea (sin bash, sin awk):

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

Si arroja 1, ¡entonces está bien!

O, reemplazando sed por tr :

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

o si le gustan los usos inútiles de los gatos y no le gustan las opciones de concatenación:

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

El truco es eliminar todos los caracteres que no sean tabuladores en cada línea, y luego orderar / unir lo que queda.

Creo que sed etc. no es adecuado para esto, una forma fácil es llamar a awk con tabulador como separador de campo:

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

lo que da

 2 1 0 

Honestamente, la forma más fácil es usar awk :

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

NF es el número de campos, -F'\t' le dice a awk que divida campos en tabs, por lo que el número de tabs será uno less que el número de campos, por lo que tenemos awk print NF-1 .

Si realmente no quieres usar awk , podrías hacerlo ( nota: esto no count las tabs finales al final de cada línea):

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

Para tratar con las tabs iniciales y finales, así como con otros caracteres extraños (como las barras diagonales inversas), haga esto en su lugar:

 $ while IFS= read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo 
  • while read lines; do ... ; done < foo while read lines; do ... ; done < foo : lee cada línea de file foo en la variable $line .
  • echo "$line" | fold -1 echo "$line" | fold -1 : el command fold imprimirá un carácter por línea
  • grep -c $'\t' : esto se ejecuta en cada línea del file ( $line ) pero como $line se ha plegado en un carácter por línea, grep -c contará el número de tabs en esa línea. Si no se fold primero, grep -c contará el número de líneas que coincidan y no le dará un conteo de tabs por línea.

También puedes usar Perl, por supuesto, pero supongo que tampoco está disponible. Aquí hay una forma, independientemente:

 perl -lne '@a=/\t/g;print scalar @a' foo 

Me revelo demasiado tarde, pero la línea de command del OP era casi correcta. Solo necesitaba $ frente a su TAB ('\ t')

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

hace exactamente lo que él estaba buscando.