2012-06-25 10 views
5

Tengo un archivo de texto que comienza con un código de colegio de 9 dígitos y termina con un código de curso de 5 dígitos.Fusiona 2 líneas en una

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, 
Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 

Hay algunas entradas en las que hay un salto de línea como se muestra en el ejemplo 3 anterior. necesito para combinar 3 y 4 de la línea en uno como primera y segunda línea, de modo que pueda utilizar fácilmente comando como grep, awk, etc.

Actualización:

no parece la respuesta de Kevin a trabajar.

cat todel.txt 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 

cat todel.txt | perl -ne 'chomp; if (/^\d{9}/) { print "\n$_" } else { print "$_\n" }' 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531ege of, 
+0

awk '/^[0-9] /,/[0-9] $ /' # no funciona – shantanuo

Respuesta

1

En cuanto a líneas divididas: Este script sed supone que tiene al menos un espacio después del número inicial (en la primera línea de la división) y un espacio antes del número final (en la última línea de la división), y que solo hay una división por línea dividida.

Modificado para aceptar entrada con Windows CRLF nuevas líneas o * nix LF. pero tenga en cuenta que la salida es un * nix \n

sed -nr 's/\r?$// # allow for '\r\n' newlines 
     /^([0-9]{9}) .* ([0-9]{5})$/{p;b} 
     /^([0-9]{9}) /{h;b} 
     /([0-9]{5})$/{x;G; s/\n//; p}' 

o, más corto, pero tal vez menos legible:

sed -nr 's/\r?$//; /^([0-9]{9}) /{/ ([0-9]{5})$/{p;b};h;b};/ ([0-9]{5})$/{x;G; s/\n//; p}' 

que se puede esperar que el primero es más rápido, ya que la prueba más frecuente (por líneas completas) implica solo una expresión regular, mientras que la segunda secuencia de comandos (más corta) necesita dos exámenes de expresiones regulares para la prueba más frecuente.

Esto es la salida que obtengo; utilizando GNU sed 4.2.1

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering,Pune 61220 enter code hereMechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
+0

# No funciona con los ejemplos que se muestran en la pregunta. ## sed versión 4.1.5 – shantanuo

+0

Eso es extraño; funciona para mí (he agregado la salida y la versión sed para responder). ¿Le da un mensaje de error o simplemente no produce la salida deseada? (tal vez no maneja la extensión regex swithc '-r' ??) –

+0

Tiene el archivo normal * nix' \ n' nuevas líneas (vs Windows '\ r \ n' o tal vez incluso el antiguo Mac' \ r')? Me he encontrado con problemas antes, al procesar archivos generados por Windows. –

0

quizás tratar de eliminar todos los saltos de línea que se producen después de las comas, así:

perl -i -pe 's/,\n/,/g' file.txt 

tal vez desee permitir en los espacios después de las comas:

perl -i -pe 's/(,\s*)\n/$1/g' file.txt 
+1

salto de línea no lo hace necesaria ocurren después de comas. – shantanuo

1

Asumiendo que su los datos están en "archivo.txt", aquí hay un escaneo que volvería a poner las líneas juntas:

cat file.txt | perl -ne 'chomp; if (/^\d{9}/) { print "\n$_" } else { print "$_\n" }' 

Esto supone que todos los registros válidos comienzan con números de 9 dígitos. El "chomp" elimina inicialmente la nueva línea, y el patrón decide dónde debe aparecer una nueva línea en la salida.

1

Esto podría funcionar para usted:

sed ':a;$!N;/ [0-9]\{5\}\n[0-9]\{9\} /!s/\n//;ta;P;D' file 

Explicación:

  • Si la línea no termina en un espacio seguido de cinco dígitos seguido de nueve dígitos y luego un espacio, elimina la nueva línea.

EDIT:

datos de prueba:

cat <<\! >/tmp/codel.txt 
> 112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
> Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
> ! 
sed ':a;$!N;/\s[0-9]\{5\}\n[0-9]\{9\}\s/!s/\n//;ta;P;D' /tmp/codel.txt 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
sed ':a;$!N;/\s[0-9]\{5\}\n[0-9]\{9\}\s/!s/\n//;ta;P;D' /tmp/{codel.txt,codel.txt,codel.txt} 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
+0

Parece que no funciona con el segundo ejemplo anterior. Pregunta actualizada – shantanuo

+0

@shantanuo probado usando sus datos nuevos (vea EDITAR) me parece bien. – potong

0

prueba este

sed '/^[0-9]\{9\}/{h;};/^[0-9]\{9\}/!{x;G;s/\n//g;}' test | grep -E '[0-9]{5}$' 
+0

No funciona con el primer archivo de ejemplo que se muestra en la pregunta. – shantanuo

0
awk '! ($1 ~ /^[[:digit:]]/) {$0 = save " " $0} $1 ~ /^[[:digit:]]/ {save = $0} $NF ~ /[[:digit:]]$/ {print}' inputfile 
+0

Esto funciona con el segundo ejemplo pero no con el primero. – shantanuo

+0

@shantanuo: El primero es el que probé y funciona bien para mí. Además, cuando lo canalizo a 'wc -l' obtengo 3. –

+0

Awk 3.1.5 devuelve 4 líneas en lugar de 3 – shantanuo

0
cat todel.txt |awk 'BEGIN {i=0} {first[i]=$1; lines[i++] = $0;} END {for (x=0; x<i; x++) { if (x==(i - 1) || (first[x + 1] ~ /^[0-9]+$/ && length(first[x + 1])==9)) {printf("%s: %s\n", x, lines[x]);} else {printf("%s: %s%s\n", x, lines[x], lines[x + 1]); x++;} } }' 
0

Esto funciona con los datos incluidos establecidos por supuesto de registros válidos terminan w ITH cinco dígitos:

use Modern::Perl; 

my $data = do{local $/; <DATA>}; 
$data =~ s/([^\d]{5})\n/$1 /sg; 
say $data; 


__DATA__ 
512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, 
Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 

Salida:

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 935315 
+0

Su expresión regular' s/([^ \ d] {5}) \ n/$ 1/sg; 'debería ser' s/^ (\ d {9}. *?) (\ n) [^ \ d {5} \ n]/$ 1/gm; 'porque si la línea encuentra un ** número con 5 dígitos en entre la línea ** y si la línea se rompe allí (que en realidad es el caso) entonces su expresión regular fallaría. Por ejemplo: considere romper en '61220' en la segunda línea. –

Cuestiones relacionadas