2010-07-18 9 views
7

Tengo un archivo de código fuente que tiene pestañas/espacios mixtos y quiero convertirlo a un archivo donde ha reemplazado automáticamente todos los espacios de sangría por pestañas para una longitud de espacio de tabulación dada (es decir, por ejemplo, tab = 2 espacios).convertir el archivo txt con espacios mixtos/pestañas solo a pestañas (donde sea posible)

¿Alguna solución fácil (con herramientas comunes de Unix, MacOSX, bash o zsh)? ¿Algun script sed o comando Python o más?

Gracias, Albert

+0

¿Puedo preguntar quién puso el voto cercano aquí? ¿Y por qué? ¿Y por qué sin comentarios? – Albert

+0

Perdón por la votación cerrada, primero pensé que esto pertenecería a superuser.com pero luego vi que no se puede hacer sin programar. – Philipp

Respuesta

0

usted podría utilizar una expresión regular para sustituir los espacios N por un charater pestaña. Por ejemplo en Python:

import re 
re.sub('[ ]{4}', '\t', text) 
+0

No es tan fácil. Esto, por ejemplo, no solo reemplazaría los espacios utilizados para la sangría sino también en cualquier otro lugar (y no debería hacer eso). – Albert

0

dos cosas,

  1. sed -i es su amigo - sed -i XXX.txt 's/^[ ]\{2\}/\t/g'
  2. No se puede hacer una expresión regular para multiplicar la sustitución pestaña por la longitud de espacio.

Dado que mi AWK-fu no es fuerte (y no sé si puede hacer lo que el # 2 no puede), escribiré un script PHP para calcular los espacios y reemplazarlos por pestañas.

+0

Ok, eso al menos solo reemplazará espacios al principio. Aunque no lo reemplazará varias veces. Probablemente escribiré un script de Python que lo haga por mí. – Albert

0
sed -r 's/ {2}/\t/g' file 
+0

No es tan fácil. Esto, por ejemplo, no solo reemplazaría los espacios utilizados para la sangría sino también en cualquier otro lugar (y no debería hacer eso). – Albert

1

Según el idioma de origen, puede probar GNU indent. Puede hacer una gran cantidad de cosas relacionadas con la sangría del código fuente, aunque podría ser más complejo de lo que necesita.

Por ejemplo, si le doy el siguiente programa a indent -di0 <inputfile>

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int i; 
    int j; 
    for (i = 0; i < 10; i++) 
    { 
     for (j = 0; j < 10; j++) 
    { 
     printf("x"); 
    } 
    } 
} 

lo reemplazará con:

#include <stdio.h> 

int 
main(int argc, char **argv) 
{ 
    int i; 
    int j; 
    for (i = 0; i < 10; i++) { 
     for (j = 0; j < 10; j++) { 
      printf("x"); 
     } 
    } 
} 

O, si necesita algo estúpido simple, no es los comandos expand/unexpand.

+0

'indent' no funciona (es Python, es difícil, también estoy buscando una solución que también funcione en otros casos). 'expand' /' unexpand' es demasiado simple (básicamente como la mayoría de las otras soluciones dadas aquí). :) – Albert

+0

Quizás la secuencia de comandos reindent.py en http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py dará una base para lo que necesita, entonces? – mjschultz

+1

Oye, ese reindent.py se parece más a lo que yo quería. :) Bueno, no se veía muy bien, no estoy seguro de si es solo de Python (lo que me habría ayudado ahora pero no hubiera sido la solución general que estaba buscando). Lo codifiqué yo mismo ahora ... – Albert

0

Aquí es una posible solución en Python:

import re 
import fileinput 

pat = re.compile("^()+") 

for line in fileinput.input(inplace=True): 
    print pat.sub(lambda m: "\t" * (m.end() // 2), line, 1), 
+0

Bien, mejor solución que las otras pero no funcionará si ya hay espacios mixtos/pestañas. Sth. como '" \ t \ t "' debería convertirse en '" \ t "* 3'. – Albert

+0

¿Funciona si reemplaza la expresión regular con '"^(| \ t) + "'? Creo que no entiendo exactamente los requisitos. __EDIT: __ es * dos * espacios en la nueva expresión regular, el marcado de código en línea desafortunadamente colapsa espacios. – Philipp

0

Esto convertirá los espacios iniciales (incluso intercalados con pestañas) en pestañas. Especifique la cantidad de espacios para convertir configurando la variable. Los espacios callejeros se colapsarán a nada. Los espacios y las pestañas que aparecen después de cualquier carácter que no sea el espacio o la pestaña no se tocarán.

tstop=2 
sed "s/^\([[:blank:]]*\)\(.*\)/\1\n\2/;h;s/[^[\n]*//;x;s/\n.*//;s/ \{$tstop\}/X/g;s/ //g;G;s/\n//g" inputfile 

Ejemplo:

[space][space][tab][tab][space][space][space][tab][space]TEXT[space][space][space] 

se convertirá en

[tab][tab][tab][tab][tab]TEXT[space][space][space] 

Si eso no es exactamente lo que está buscando, se pueden hacer ajustes.

+0

Totalmente ilegible pero se parece a lo que estaba buscando. :) Por cierto, ¿no debería ser '... [tab] [espacio] TEXTO' en la salida? Al menos eso es lo que quiero. – Albert

+0

Estoy eliminando todos los espacios perdidos. ¿Qué quieres (para 'tstop = 2')' [tab] [espacio] [tabulación] ... TEXT' para que parezca? ¿Qué pasa con '[tab] [space] [space] TEXT'? –

+0

'[t] [s] [t] text' debe convertirse en' [t] [t] text'. '[t] [s] [s] text' debe convertirse en' [t] [t] text'. '[t] [s] text' debe permanecer igual. – Albert

Cuestiones relacionadas