2010-08-26 43 views
5

Gracias por tomarse el tiempo para leer esto y apreciaré cada respuesta, no importa la calidad del contenido. :)Archivo de texto de ordenación PHP (.txt) numéricamente

Usando php, intento crear una secuencia de comandos que ordenará numéricamente un archivo de texto (.txt) en orden ascendente (de menor a mayor). Cada entrada dentro del archivo de texto está en una nueva línea, por lo tanto, me gustaría que las líneas se clasifiquen numéricamente. Si es posible, una vez que se haya ordenado numéricamente, me gustaría que los datos se escriban en otro archivo de texto, titulado "newtime.txt" dentro del mismo directorio. Por supuesto, si es posible. ;)

La parte principal con la que estoy luchando es que el contenido dentro del archivo de texto no es estático (por ejemplo, contiene x número de líneas/palabras, etc.) De hecho, se actualiza automáticamente con varias líneas. Por lo tanto, me gustaría que todas las líneas se actualicen numéricamente.

El archivo de texto sigue la estructura:

2 aullah1 
12 name 
7 username 

Por supuesto, que se actualiza regularmente con más líneas. ¿Será posible ordenar numéricamente las líneas? Además, planeo usar un Cron Job para repetir el script cada 5 minutos. ;)

P.S. ¿Qué pasará si hay dos mismos números? ¿Luego irá a ordenar los datos alfabéticamente?

Toda la ayuda es apreciada y espero con interés sus respuestas; gracias. :) Si no le expliqué nada claramente y/o me gustaría que lo explicara con más detalle, responda. :)

Gracias.

Respuesta

5

Asumiendo estás trabajando con un número razonable de líneas (miles, no millones) esto debería ser suficiente. Si tiene archivos muy grandes, es posible que encuentre problemas de memoria utilizando file():

<?php 

$data = file($file_path); 
natsort($data); 
file_put_contents($new_file_path, implode("\n", $data)); 

Se podría sustituir a la única file_put_contents con un bucle fwrite() para cada elemento de datos de $.

natsort() ordenará los números correctamente (a diferencia de asort() que pondrá 10 antes 2). Para hacer coincidir los números, se ordenará como espera, comparando el resto de la cadena.

natsort(), file()

+0

Hola jasonbar, gracias por tu respuesta, lo aprecio muchísimo, así como su esfuerzo. Probé tu codificación y funcionó más que perfectamente y es lo que usaré. De nuevo, no puedo agradecerte lo suficiente. ;) – AUllah1

+0

¿Qué vas a hacer cuando haya 500 mil millones de filas para ordenar? Las soluciones en memoria no se escalan. Utilice las funciones dba _ *() con qdbm. Construya su base de datos, utilizando las claves derivadas como claves y las líneas originales como valores. Construya sus claves de modo que clasifiquen en el orden que necesita, luego realice un escaneo secuencial en la base de datos, obteniendo los valores (las líneas originales) en un nuevo archivo ordenado. Luego cierre y elimine la base de datos. –

5

Usted puede hacer esto fácilmente

Leyendo el archivo en una matriz:

$lines = file($path_to_file); 

ordenar la matriz:

natsort($lines); 

Escribir la matriz de nuevo a un nuevo archivo:

file_put_contents($path_to_new_file, implode(PHP_EOL, $lines)); 
+2

La última línea debería ser: 'file_put_contents ($ path_to_new_file, implode (PHP_EOL, $ lines));' – shamittomar

+0

Gracias, por corregirme – Mischa

+0

Hola captaintokyo, gracias por tu respuesta. ¡Es muy apreciado! Tu guión funcionó perfectamente en todos los aspectos, pero hubo un problema, que fue señalado por jasonbar (scroll down). Parece mostrar 10 más bajo que 2, ya que 10 tiene el dígito 1, que es más bajo que 2. :(De nuevo, aprecio su respuesta y estoy muy agradecido por su esfuerzo.;) – AUllah1

3
<?php 
$lines = file("time.txt"); 
natsort($lines); 
file_put_contents("newtime.txt", implode("\n", $lines)); 
?> 
+0

Hola Mike, agradezco tu respuesta. Definitivamente tienes una habilidad dentro de la codificación php y tu código también funciona perfectamente. De nuevo, gracias por su respuesta y no puedo agradecerles lo suficiente por su esfuerzo. ;) – AUllah1

1

Esto es, con mucho, la solución más rápida y más elegante que he encontrado, cuando tuve el mismo problema. Si estás en Linux (con exec permitido en la configuración de PHP) que puede hacer las siguientes (siempre que se desea ordenar los archivos de forma numérica):

exec("sort -n " . $pathToOriginalFile . " > " . $pathToSortedFile); 

Básicamente, ejecutar el comando de bash tipo que ordena las líneas en un archivo numéricamente Si desea mantener los datos en el archivo original a hacer esto:

exec("sort -n " . $pathToOriginalFile . " > " . $pathToSortedFile); 
exec("rm " . $pathToOriginalFile); 
exec("mv " . $pathToSortedFile . " " . $pathToOriginalFile); 

Si desea una clasificación alfabética solo excluye la opción -n (--numeric-especie).

exec("sort " . $pathToOriginalFile . " > " . $pathToSortedFile); 

Para mí, el comando tomó aproximadamente 3 segundos para ordenar 10 millones de líneas en el archivo en el servidor.

Puede encontrar más información sobre tipo aquí http://www.computerhope.com/unix/usort.htm

espero que ayude.

+0

¿Quizás sepa cómo hacerlo en Win? Tengo una cantidad de filas "irrazonables" (promedio de 10-20 millones). –

+0

Uhm, ¿por qué alguna vez usarías el servidor Win para la aplicación PHP? Para ser sincero, no tengo idea de cómo hacer esto en Win, pero pasa lo antes posible a Linux u OS X, para cualquier tipo de trabajo PHP. –

+0

Tengo un servidor temporal en la máquina de escritorio en el trabajo. Pero, sorprendentemente, shuffle() para los registros de 10M tomó aproximadamente 5 segundos :) De todos modos, gracias por la respuesta :) –

Cuestiones relacionadas