# [BASH] Contar caracteres en un archivo de texto (cerrado).

## Inodoro_Pereyra

Buenas, tengo dos archivos de texto plano con casi 700.000 líneas. 

Estoy tratando de eliminar todas las líneas que tienen 4 o menos caracteres, que son unas cuantas miles, y no encuentro o no me doy cuenta como hacerlo.

Algún mago de bash que me saque del paso?

Salud!

----------

## will198

Hola Inodoro_Pereyra

No se si te puede servir, pero en una asignatura que tuve de pascal teníamos que crear un ejercicio en Pascal que contase caracteres y eliminase ciertos caracteres... creo que no sería dificil modificarlo para que hiciese lo que dices...

Si no encuentras una solución mejor, sabes pascal y te interesa te lo buscar y pasar...

Un saludo

----------

## natxoblogg

no seria con:

```
grep -v *{,3} tu-archivo > nuevo archivo
```

el *{,3} representa cualquier caracter de 0 a 3 veces en una linea.

de todas formas tengo dudas de si será el mismo caracter repetido o cualquiera. Por si acaso para no liarla haz la prueba en algun archivo de prueba.

----------

## natxoblogg

Te buscare sintaxis de flex, puesto que bash está echa con flex y bison, pero lo que te interesa es en este caso flex.

----------

## will198

Hola,

¿Como se puede adjuntar fichero aquí?...

Bueno te posteo el Código de Pascal más abajo... es un poco chapucero pero como te he contado he cogido un un programa que he tendo y le he metido un par de modificaciones... por cierto los ficheros tienen que ser de texto plano... espero que te sirva... te pongo un par de comentarios por si no tienes ni idea de pascal

Lo tienes que compilar con el FPC así:  fpc EliminaLineas2.pas (Si no lo tienes emerge fpc)

y luego lo ejecutas así: ./EliminaLineas2 (No se por qué no funciona con sh EliminaFilas2)

El fichero que quieres meterle se tiene que llamar: AEntrada.txt y tiene que estar en el mismo directorio que el fichero de EliminaFilas2. Crea un ASalida.txt que es el fichero de salida = que el de entrada pero sin las líneas de 4 o menos caracteres... por cierto está programado para que las líneas tengan menos de 999 caracteres.

Al final te pongo el contenido de AEntrada.txt y ASalida.txt que es con lo que lo he probado:

Te pongo como me quedó a mi el directorio:

-rw-r--r-- 1 alex wheel     92 ago 23 21:23 AEntrada.txt

-rw-r--r-- 1 alex wheel      0 ago 23 21:22 AEntrada.txt~

-rw-r--r-- 1 alex wheel     68 ago 23 21:27 ASalida.txt

-rwxr-xr-x 1 alex wheel 112732 ago 23 21:26 EliminaLineas2

-rw-r--r-- 1 alex wheel   3952 ago 23 21:26 EliminaLineas2.o

-rw-r--r-- 1 alex wheel   1852 ago 23 21:26 EliminaLineas2.pas

-rw-r--r-- 1 alex wheel   1851 ago 23 21:26 EliminaLineas2.pas~

EL CÓDIGO DE PASCAL:

PROGRAM NumLine(Input, AEntrada, ASalida, Output);

{**************************************

Entrada (ArchEntrada)

Objetivo : Numerar las l¡neas de una rachivo del 1 al x

Salida : ArchSalida

****************************************}

CONST

	MaxCad = 999;

TYPE

        TipoCadena = ARRAY[0..MaxCad] OF Char;

        TipoReg = RECORD

                        Cima : Integer;

                        Datos : TipoCadena;

                        END;

VAR

        Pila : TipoReg;

        AEntrada : Text;

        ASalida  : Text;

	i 	 : Integer;

        Caracter : Char;

FUNCTION PilaLlena(VAR Pila : TipoReg) : Boolean;

        BEGIN

                Pilallena := (MaxCad = Pila.Cima);

        END;

FUNCTION PilaVacia(VAR Pila : TipoReg) : Boolean;

        BEGIN

                PilaVacia := (Pila.Cima = 0);

        END;

PROCEDURE IniciaPila(Var Pila: TipoReg);

	BEGIN

		Pila.Cima := 0;

	END;

PROCEDURE Apila(VAR Pila : TipoReg; Dato : Char);

        BEGIN

                IF Pilallena(Pila) THEN WRITELN('Pila llena')

                ELSE BEGIN

                        Pila.Cima := Pila.Cima + 1;

                        Pila.Datos[Pila.Cima] := Dato;

                        END;

        END;

BEGIN

	Assign(AEntrada, 'AEntrada.txt');

	Reset(AEntrada);

	Assign(ASalida, 'ASalida.txt');

	Rewrite(ASalida);

        WHILE NOT Eof(AEntrada) DO

                BEGIN

			IniciaPila(Pila);

                        WHILE NOT Eoln(AEntrada) DO

				BEGIN

	                                Read(AEntrada, Caracter);

					Apila(Pila, Caracter);

                		END {Fin Eoln};

			IF Pila.Cima > 4 THEN BEGIN

				For i := 1 TO Pila.Cima DO BEGIN

					Write(ASalida, Pila.Datos[i]);

				End;

				WRITELN(ASalida);			

			END;

			Readln(AEntrada);

	        END {Fin Eof};

	Close(AEntrada);

	Close(ASalida);

END.

ARCHIVO DE ENTRADA:

12345678

1234

123456

12

1

123456

12

123456789

1

111111

123

1234567890

123456

123

123456789

ARCHIVO DE SALIDA:

12345678

123456

123456

123456789

111111

1234567890

123456

123456789

----------

## will198

Leches, las sangrias se me han ido a hacer puñetas... espero que aun así se entienda el código.

He probado a copiar y pegar el codigo tal cual y funciona... Con copiarlo a un fichero creado con cualquier editor que termine en .pas vale.

Hay que copiar desde PROGRAM hasta el último END.

Un saludo

----------

## pcmaster

Para que nos e vayan las sangrías usa 

```
[code] y [/code]
```

 Lo tienes encima del cuadro donde se escriban las respuestas.

----------

## Inodoro_Pereyra

Bueno, les agradezco a todos, al final, después de dos horas de prueba y error, manuales y ejemplos de grep y expresiones regulares POSIX, he llegado a este comando que hace exactamente lo que necesito:

```
grep '[A-Za-z0-9_-]\{4\}\#\+' base11.txt > basefinal.txt
```

La pista me la dió natxoblogg, muchas gracias!

Ya estaba empezando a mirar con cariño eso de compilar pascal  :Very Happy: 

Donde está i92 cuando lo necesito? jeje...

Salud!

----------

## natxoblogg

Nos tenemos que poner más con bash, yo es algo que tengo pendiente, junto con python.

si quieres te pasaré manuales de flex, por lo menos es lo que ami más me ha servido para poder entender más el bash.

----------

## Inodoro_Pereyra

La programación no es lo mío, definitivamente, me atraen mas otras cosas. Solo me pongo a aprender cuando necesito algo puntual   :Embarassed: 

Te agradezco el ofrecimiento pero tengo tantas cosas pendientes por leer que seguramente el manual de flex ese quedaría relegado al final, jeje...

Salud!

----------

## will198

Es una lástima que no se pueda anexar fichero, si no te podía haber enviado el fichero compilado y te hubieses ahorrado las dos horas... pero seguro que no fueron dos horas perdidas sino que aprendistes más cosas del BASH.

Ami si que me encanta programar, la verdad es que hace un par de años me bajé un par de tutoriales básicos para hacer bash sript pero esto es como todo si no lo usas se olvida... y la verdad es que no tengo ahora mismo nada en mente para programar en BASH...

Lo de Python me atráe mucho (Me he bajado un tutorial de Python y lo he comenzado a leer), pero como con el Bash... si no tengo nada en la cabeza para programar... aprender por aprender no sirve...

Con lo que estoy ahora más enfrascado es con VBA, porque ahí si que tengo un objetivo, me estoy haciendo un monton de aplicaciones para mi curro con el objetivo de automatizar al máximo mi trabajo diario, luego me traigo un muñeco tamaño natural y ya...sta, llego por la mañana, ficho entrada ejecuto las aplicaciones, pongo el muñeco y vuelvo a la hora de la salida con todos los informes hechos, quito muñeco ficho salida y me piro...

Saludos a todos

PD: ¿Alguno sabe de algun tutorial para hacer muñecos a tamaño natural?

----------

## Inodoro_Pereyra

Jeje, buenísimo lo del muñeco.   :Very Happy: 

Salud!

----------

