Numerar las líneas de un texto para una revisión entre varias personas
Publicado el 12/8/2026 · 16 min de lectura · Herramientas de texto e idioma
Daniel Okonkwo — Desarrollador front-end y redactor de Tecnología en Allin
Rendimiento web · Formatos de archivo
Verificado con 3 fuentes
Pega el texto en add-line-numbers y cada línea recibe un número delante, empezando por 1. La casilla «Empezar en» acepta otro valor, pero no el cero: el código lee Number(start) || 1, y 0 es falsy, así que 0 vuelve a ser 1. Los inicios negativos sí funcionan: pon −3 sobre tres líneas y obtienes −3, −2, −1. La alineación es automática y usa espacios, nunca ceros a la izquierda: el ancho lo marca el último número, de modo que 102 líneas dan « 1. » hasta « 102. », y un texto de 99 líneas da « 1. » con un solo espacio. El separador por defecto es un punto y un espacio; se ofrecen otros diez, entre ellos « 1) », « 1: », « [1] », « #1 » y un tabulador. La vuelta es asimétrica, pero ya no es destructiva. remove-line-numbers conoce un solo patrón —espacios iniciales, cifras, un separador tomado de un juego de ocho y después un solo espacio o el final de la línea—, así que deshace ocho de los once y deja adrede el guion, la barra vertical y el espacio simple: «10 - 20 people» y «1 | Alice | 30» son contenido mucho más a menudo que numeración. Como ahora toma un único espacio en vez de una secuencia codiciosa, numerar JavaScript indentado y quitarle el número devuelve el código byte a byte, con su indentación. Y como un separador tiene que ir seguido de un espacio, «3.14 is pi» y «12.50 Coffee» se quedan donde están. Lo que ninguna regla puede salvar es una línea idéntica a la salida de la propia herramienta: «2026. A year.» sigue volviendo como «A year.» Numera una copia y guarda el original.
La numeración empieza en 1 y no se puede poner a 0, la alineación se hace con espacios y no con ceros, y la herramienta que los quita deshace ocho de los once separadores sin tocar la indentación. Lo que sigue sin poder hacer es distinguir tus números de los suyos.
Por qué un texto compartido necesita números
El código llega con sus números puestos. El editor los muestra en el margen izquierdo, un diff los imprime a ambos lados del cambio y un comentario de revisión en una plataforma de alojamiento se ancla a uno de ellos. La prosa no. Una cláusula de contrato, un juego de subtítulos, una exportación de memoria de traducción, una lista de nombres de producto que deben revisar dos compañeros: ninguno de esos textos tiene una manera estable de decir «el cuarto empezando por arriba» que no sea contar.
El recuento a mano es donde la revisión se tuerce. Dos personas cuentan desde puntos distintos, una incluye la línea en blanco y la otra no, y una hora después hay dos correcciones sobre la misma cláusula y una sobre una cláusula que nadie quería tocar. Poner un número en cada línea antes de hacer circular el texto elimina toda esa familia de malentendidos al precio de un pegado.
La palabra importante es «antes». Los números son un sistema de coordenadas, y un sistema de coordenadas solo sirve mientras no se mueve. Si alguien renumera un texto ya anotado, cada comentario se vuelve una adivinanza. Numera una vez, haz circular exactamente esa versión y recoge las correcciones contra ella.
Lo que la herramienta produce de verdad
Por defecto es un punto y un espacio: «first line» pasa a ser «1. first line». Se ofrecen otros diez separadores: «1) », «1: », «1 - », «1 | », «[1] », «1] », «#1 », «1 → », un espacio simple y un tabulador. Dos de ellos envuelven el número en lugar de seguirlo, y por eso «[1] » y «#1 » tienen otro aspecto.
La alineación se calcula a partir del último número y se aplica con espacios normales, no con ceros. Un texto de 102 líneas vuelve con « 1. line1» arriba y « 102. line102» abajo, con las cifras alineadas a la derecha. El ancho se decide una sola vez, antes de escribir la primera línea, así que un texto de 99 líneas tiene ancho dos y uno de 100 líneas tiene ancho tres: un espacio más en cada línea por una sola línea añadida. Si comparas dos versiones numeradas, esa es la razón de que todas las líneas salgan como modificadas.
Conviene conocer tres comportamientos pequeños antes de pegar algo largo. Un salto de línea final produce una línea vacía numerada al final, porque dividir «a\nb\n» por los saltos da tres trozos y el tercero está vacío: la salida termina en «3. ». Una entrada vacía produce «1. » en lugar de nada. Y una entrada con finales de línea de Windows vuelve con finales de Unix: la división acepta un retorno de carro antes del avance de línea, pero la unión solo devuelve el avance de línea.
Empezar en 1, y solo en 1 — o en un número negativo
La casilla «Empezar en» existe porque un extracto numerado suele venir de algún sitio: la página cuatro de una transcripción no debería volver a empezar en 1. Ponla en 500 y la salida da 500, 501, 502, con un ancho de tres. Hasta ahí funciona tal como se anuncia.
El cero es la excepción, y no es un fallo que se sortee escribiéndolo de otra forma. El valor se lee como Number(start) || 1. El cero es uno de los valores falsy de JavaScript, así que la expresión cae en 1: escribir 0 y no escribir nada dan el mismo resultado. Quien quisiera una numeración al estilo de los arrays, con la primera línea como línea 0, no la tendrá aquí. Una casilla vacía se comporta igual, y un valor que no es un número tampoco cambia nada: «abc» da 1.
Los inicios negativos, curiosamente, sí funcionan, porque −3 es truthy. Tres líneas que empiezan en −3 vuelven como «-3. », «-2. », «-1. »: no sirve para nada en concreto, pero indica que la salvaguarda va sobre la falsiness y no sobre el signo. Los valores fraccionarios se redondean hacia menos infinito: 2,7 pasa a 2 y −2,7 pasa a −3.
La vuelta, que no es simétrica
remove-line-numbers no tiene ninguna opción. Aplica un solo patrón a cada línea: espacios o tabuladores iniciales, luego el número y su marca —cifras seguidas de un tabulador, o cifras entre corchetes o precedidas de una almohadilla, o cifras seguidas de un punto, un paréntesis de cierre, dos puntos, un corchete de cierre o una flecha— y después un solo espacio, o el final de la línea. Todo lo que coincide se borra, una vez por línea. Dos detalles de esa frase hacen todo el trabajo: la marca tiene que ir seguida de un espacio, y el espacio que se consume es exactamente uno.
Pasa los once separadores por la herramienta y ocho sobreviven al viaje: punto, paréntesis, dos puntos, tabulador, «[1] », «1] », «#1 » y «1 → » vuelven exactamente al texto original. Tres no, y la omisión es deliberada. «1 - alpha», «1 | alpha» y «1 alpha» vuelven sin cambios, con los números todavía puestos, porque «5 - 3 = 2», «10 - 20 people», «1 | Alice | 30» y «007 James» tienen exactamente la misma forma y son contenido mucho más a menudo que numeración. Una herramienta de borrado que deshiciera esos tres se comería una fila de hoja de cálculo cada vez que alguien pegara una.
El patrón terminaba con una secuencia codiciosa de espacios que se llevaba la indentación propia del texto; ahora toma exactamente uno. Numera cinco líneas de JavaScript con una función, un if y un return, quítales el número, y el archivo vuelve byte a byte, con sus indentaciones. YAML y Python se comportan igual, y ahí es donde más importa: en esos dos lenguajes un resultado aplanado no solo es feo, ya no significa lo mismo.
Una herramienta de borrado no sabe de quién es el número
Este es el límite honesto de toda la idea, y la regla del espacio lo estrecha sin eliminarlo. «1. Lavar el arroz» es una línea numerada si el 1 lo puso la herramienta, y contenido si lo puso el cocinero. Nada en la cadena distingue una cosa de la otra, y ningún patrón puede: esas dos líneas son los mismos bytes. Exigir un espacio tras el separador descarta los accidentes —«3.14 is pi» y «1.2.3 version» vuelven ahora intactos, porque un punto decimal nunca va seguido de un espacio—, pero no descarta las coincidencias. «12: 30 departure» sigue volviendo como «30 departure». «2026. A year.» sigue volviendo como «A year.» Ambas son, carácter por carácter, lo que escribe add-line-numbers; sobre una línea que nadie numeró, eso sigue siendo pérdida de datos.
Dos cosas mantienen a salvo el caso corriente. El borrado ocurre una vez por línea y se detiene en el primer separador: una lista de precios escrita a la inglesa, numerada, da «1. 12.50 Coffee», y quitarle el número reconoce «1. » y se detiene, devolviendo «12.50 Coffee» intacto; una lista que ya tenía sus propios números, «1. 1. alpha», pierde exactamente un nivel. Y esa línea de precio sobrevive ahora incluso sin la numeración, porque el punto de «12.50» no va seguido de un espacio. El viaje de ida y vuelta es, pues, seguro sobre cualquier texto, indentado o plano, con cualquiera de los ocho separadores. Lo que aún muerde es la herramienta de borrado sola, aplicada a un texto que nadie numeró, sobre el estrecho conjunto de líneas que se parecen a su propia salida.
Entender por qué algo es seguro resulta más útil que la lista. Un CSV de identificadores sobrevive —«1024, Dupont, 42» vuelve intacto— porque el carácter posterior a las cifras es una coma, y la coma no aparece en ninguna de las formas de marca. «100 units of flour» y «007 James» sobreviven porque un espacio simple tampoco es una. Los decimales y las versiones semánticas también son seguros, pero por la otra razón: «3.14» y «1.2.3» sí llevan un punto, y lo que los salva es que no le sigue ningún espacio. Lo que corre peligro es el estrecho conjunto en que un número, una marca reconocida y un espacio llegan en ese orden: los años usados como títulos, «12: 30» escrito con espacio tras los dos puntos, y —novedad desde que se amplió el juego de marcas— las llamadas de nota del tipo «[1] » y las líneas que abren con «#1 ».
Llevar la revisión sin perder nada
Guarda el original sin numerar en un sitio donde no vayas a sobrescribirlo y trata la versión numerada como una impresión: algo para leer, citar y anotar, no para editar y devolver. Cada corrección recogida como «línea 47, sustituir X por Y» se aplica limpiamente al original, y los números no hay que quitarlos nunca.
Si de verdad piensas quitar los números después, evita exactamente tres separadores: el guion, la barra vertical y el espacio simple. Todo lo demás del menú —punto, paréntesis, dos puntos, tabulador, «[1] », «1] », «#1 », «1 → »— se quita sin problema. Prefiere el tabulador si el texto va a pasar cerca de una hoja de cálculo: pone los números en su propia columna.
Numerar código que pienses volver a pegar es ahora viable, cosa que antes no lo era: con un punto, un paréntesis, dos puntos o un tabulador, el archivo vuelve byte a byte, con su indentación. Sigue siendo pocas veces el gesto acertado —una revisión de código tiene mejores instrumentos: un diff, una pull request o simplemente los números de línea que el editor ya os muestra a los dos—, pero si lo haces, elige uno de esos cuatro y prueba antes el viaje de ida y vuelta sobre una copia.
| Entrada | Resultado | Por qué |
|---|---|---|
| «Empezar en» puesto a 0, dos líneas | 1. a y 2. b | Number(start) || 1 — el cero es falsy, así que pasa a 1 |
| «Empezar en» puesto a −3, tres líneas | -3. a, -2. b, -1. c | Un número negativo es truthy, así que la salvaguarda lo deja pasar |
| Un texto de 102 líneas, separador por defecto | « 1. » arriba, « 102. » abajo | Alineado a la derecha con espacios; el ancho lo da el último número |
| Texto que termina con un salto de línea | Una línea vacía numerada al final | Dividir por los saltos de línea da un trozo más que líneas de texto hay |
| «1 - alpha» por remove-line-numbers | Sin cambios | El guion se deja fuera adrede: «10 - 20 people» es contenido mucho más a menudo que numeración |
| Cinco líneas de JavaScript indentado, numeradas y desnumeradas | El código vuelve byte a byte, con sus indentaciones | El patrón toma exactamente un espacio tras el separador, no una secuencia codiciosa |
| «3.14 is pi», nunca numerada, por la herramienta de borrado | Sin cambios | Un separador tiene que ir seguido de un espacio, y un punto decimal nunca lo está |
| «1024, Dupont, 42», nunca numerada, por la herramienta de borrado | Sin cambios | La coma no aparece en ninguna de las ocho formas de marca, así que nada coincide |
| «1. 12,50 Café», numerada por la herramienta, por la herramienta de borrado | «12,50 Café» — el viaje de ida y vuelta no pierde nada | La sustitución se ejecuta una vez por línea y se detiene en el primer separador |
Preguntas frecuentes
- ¿Puedo hacer que la numeración empiece en 0?
- No, y no hay truco que lo sortee. La herramienta lee la casilla como Number(start) || 1. El cero es falsy en JavaScript, así que la expresión lo descarta y devuelve 1: escribir 0, dejar la casilla vacía o escribir una palabra producen todos una lista que empieza en 1. Se comprobó con 0, «0», «» y «abc», y los cuatro dieron la misma salida. Si necesitas numeración desde cero, numera desde 1 y resta uno mentalmente, o numera desde −1 si lo que importa es el desfase y no el signo: los inicios negativos sí funcionan, porque un número negativo es truthy.
- ¿Seguirán alineados los números cuando el texto pase de 100 líneas?
- Sí. El ancho se calcula a partir del último número antes de escribir nada, y cada número se rellena por la izquierda con espacios hasta ese ancho. Un texto de 102 líneas empieza con dos espacios delante de la línea 1 y ninguno delante de la 102: los puntos forman una columna recta. No hay ceros a la izquierda: obtienes « 7. », nunca «007. ». Una consecuencia pilla a mucha gente: un texto de 99 líneas usa ancho dos y el mismo texto con una línea más usa ancho tres, así que cada línea cambia en un espacio. Si comparas dos versiones numeradas con un diff, esa es la razón de que todo el archivo parezca modificado. Compara mejor los originales.
- ¿remove-line-numbers deshace siempre lo que hace add-line-numbers?
- No, pero las razones han cambiado. Reconoce ocho de los once separadores —punto, paréntesis de cierre, dos puntos, tabulador, «[1] », «1] », «#1 » y «1 → »— y deja adrede el guion, la barra vertical y el espacio simple, porque «10 - 20 people», «1 | Alice | 30» y «007 James» tienen la misma forma y suelen ser contenido. Con un separador reconocido, el viaje de ida y vuelta es ahora byte a byte, con la indentación incluida: cinco líneas de JavaScript con un cuerpo de función indentado a cuatro y ocho espacios entraron y volvieron idénticas, y lo mismo con YAML, Python y una lista de precios plana.
- Pasé la herramienta de borrado por una lista de precios y se comió parte. ¿Qué ha pasado?
- Ya no puede hacerlo. La herramienta borraba antes las cifras iniciales seguidas de un punto, un paréntesis de cierre, dos puntos o un tabulador, sin exigir nada detrás: de ahí que «3.14 is pi» pasara a «14 is pi» y «12.50 Coffee» a «50 Coffee». El patrón exige ahora un espacio, o el final de la línea, después del separador, y un punto decimal nunca va seguido de un espacio: «3.14 is pi», «1.2.3 version» y «12.50 Coffee» vuelven todos intactos. Lo que todavía puede llevarse es una línea con la forma exacta de su propia salida —«2026. A year.» da «A year.», «12: 30 departure» da «30 departure»— y, desde que se amplió el juego de marcas, las llamadas de nota: «[1] See note» da «See note». Una lista separada por comas es segura en cualquier caso, porque la coma no aparece en ninguna forma de marca.
- ¿Debo numerar código fuente para una revisión de código?
- Por lo general no, aunque ya no sea arriesgado. El código ya lleva números de línea allí donde se lee —en el margen del editor, en un diff, en la interfaz de revisión de cualquier plataforma—, así que numerarlo sobre todo añade ruido. Ahora sí sobrevive al viaje de ida y vuelta: con un punto, un paréntesis, dos puntos o un tabulador, numerar un archivo indentado y quitarle los números lo devuelve byte a byte, con su indentación, cosa que antes no ocurría. Tres separadores siguen sin quitarse nunca —el guion, la barra vertical y el espacio simple—, así que evítalos si los números tienen que salir. La numeración se gana su sitio en textos que no tienen números propios y se leen fuera de una herramienta que los proporcione: un contrato distribuido como documento, un archivo de subtítulos discutido en un hilo, una lista de cadenas enviada a un traductor. Si revisas código y la plataforma queda lejos, citarlo en un bloque y referirte a él por nombre de función sigue siendo la vía más tranquila.
Artículos que podrían interesarte
Todas las guías →Herramientas relacionadas
Todo lo que sigue describe lo que hacen hoy estas cuatro herramientas, comprobado ejecutando su propio código sobre las entradas exactas que aparecen en cada artículo, y no lo que una norma les obligue a hacer. Cuando una herramienta falla en un caso, queda escrito con claridad en vez de sortearlo, y no se ha cambiado nada para que un artículo se lea mejor. Dos consecuencias. Pasa cualquier transformación primero sobre una copia y compara los dos extremos: una herramienta de texto que borra algo no lo anuncia. Y da un secreto por compartido en cuanto sale de la página: pegarlo en una conversación, un ticket o un repositorio lo quema, por bien generado que estuviera.
Fuentes
¿Has detectado un error en este artículo?