¿Los finales de línea difieren entre Windows y Linux?

Estoy tratando de analizar el /etc/passwd Linux /etc/passwd en Java. Actualmente estoy leyendo cada línea a través de la clase java.util.Scanner y luego usando java.lang.String.split(String) para delimitar cada línea.

El problema es que la línea:

 list:x:38:38:Mailing List Manager:/var/list:/bin/sh" 

es tratado por el escáner como 3 líneas diferentes:

  1. list:x:38:38:Mailing
  2. List
  3. Manager...

Cuando escribo esto en un archivo nuevo que no obtuve de Linux, Scanner analiza correctamente.

¿Hay algo que no entiendo sobre nuevas líneas en Linux?

Obviamente, una solución es analizarlo sin usar el escáner, pero no sería elegante. ¿Alguien sabe de una manera elegante de hacerlo?

¿Hay alguna manera de convertir el archivo en uno que funcione con Scanner ?


Ni siquiera hace dos días: Razón histórica detrás de diferentes terminaciones de línea en diferentes plataformas

EDITAR

Nota del autor original:

“Descubrí que tengo un error diferente que está causando el problema. No tengo en cuenta la pregunta”

De la Wikipedia :

  • LF: sistemas de Multics, Unix y Unix (GNU / Linux , AIX, Xenix, Mac OS X , FreeBSD, etc.), BeOS, Amiga, RISC OS y otros
  • CR + LF: DEC RT-11 y la mayoría de los sistemas operativos anteriores que no son Unix, que no son de IBM, CP / M, MP / M, DOS , OS / 2, Microsoft Windows , SO Symbian
  • CR: máquinas Commodore, familia Apple II, Mac OS hasta la versión 9 y OS-9

Traduzco esto en estos finales de línea en general :

  • Windows: '\r\n'
  • Mac (OS 9-): '\r'
  • Mac (OS 10+): '\n'
  • Unix / Linux: '\n'

También necesita hacer que su escáner / analizador maneje la versión de Unix.

Puede obtener la terminación de línea estándar para su sistema operativo actual desde:

 System.getProperty("line.separator") 

El escáner se está rompiendo en los espacios.

EDITAR : El tutorial de ‘escaneo’ de Java dice:

De forma predeterminada, un escáner usa espacios en blanco para separar tokens. (Los espacios en blanco incluyen espacios en blanco, tabs y terminadores de línea. Para ver la lista completa, consulte la documentación de Character.isWhitespace).

Puede usar el método useDelimiter () para cambiar estos valores predeterminados.

Esto funciona para mí en Ubuntu

 import java.util.Scanner; import java.io.File; public class test { public static void main(String[] args) { try { Scanner sc = new Scanner(new File("/etc/passwd")); String l; while( ( l = sc.nextLine() ) != null ) { String[] p = l.split(":"); for(String pi: p) System.out.print( pi + "\t:\t" ); System.out.println(); } } catch(Exception e) { e.printStackTrace(); } } } 

¿Has intentado eliminar todos los caracteres ocultos pero ‘\ n’. ¿Cuál es la expresión regular que estás usando para dividir las líneas?

¿Por qué no utilizar LineNumberReader ?

Si no puede hacer eso, ¿cómo se ve el código?

La única diferencia que puedo pensar es que te estás dividiendo en una expresión regular incorrecta y que cuando editas el archivo tú mismo, obtienes dos nuevas líneas que de alguna manera pasan tu expresión regular.

Aún así, para leer cosas una línea a la vez, parece exagerado usar Scanner .

Por supuesto, ¿por qué está analizando /etc/passwd es un agujero otra discusión 🙂

Ahora recuerdo por qué uso BufferedReader en estas ocasiones … 🙂