Ir al contenido
Allin

Filtrar líneas por un patrón sin línea de comandos

Publicado el 7/8/2026 · 11 min de lectura · Herramientas de texto e idioma

Daniel Okonkwo

Daniel OkonkwoDesarrollador front-end y redactor de Tecnología en Allin

Rendimiento web · Formatos de archivo

Verificado con 3 fuentes

Ver perfil
En resumen

filter-lines divide tu texto por los saltos de línea, comprueba en cada línea la presencia de una subcadena, y la conserva o la descarta. La comparación es un includes de cadena sobre un término literal: no hay motor de expresiones regulares detrás del cuadro. Escribir ^ERROR en un registro no devolvió nada; ERROR|WARN tampoco; [a-z]+ tampoco. Cada uno produjo un panel de salida vacío, sin mensaje de error y sin aviso de que el patrón se había leído literalmente, y ese es el comportamiento que hay que conocer antes de empezar. Lo contrario también es cierto y resulta más tranquilizador: una expresión regular inválida es inofensiva aquí, porque no es una expresión regular. Escribir un simple paréntesis de apertura sí conservó la línea que contiene uno, exactamente como querrías. «Ignorar mayúsculas» está activo por defecto: filtrar por apple conservó la línea APPLE juice igual que apple pie; grep en un terminal distingue mayúsculas por defecto y esta herramienta no, diferencia que conviene tener presente si estás acostumbrado a una de las dos. La acción ofrece «Conservar líneas coincidentes» y «Eliminar líneas coincidentes», que corresponden a grep y grep -v. Dejar el término vacío devuelve tu texto sin cambios, no nada. Dos detalles de las pruebas: el modo eliminar conserva las líneas vacías, porque una línea vacía no contiene tu término, así que un registro filtrado vuelve con los huecos que dejaron las líneas quitadas; y toda la salida se une con saltos de línea simples, de modo que un archivo de Windows pierde sus retornos de carro por el camino.

Esto es grep para quien no usa grep, con una diferencia importante: la búsqueda es una subcadena literal, así que una expresión regular de verdad devuelve un cuadro vacío y ningún error. Cada afirmación se comprobó ejecutando la herramienta.

Qué hace grep, y qué mitad está aquí

grep lee un texto línea a línea, contrasta cada línea con un patrón y escribe las que coinciden. La especificación POSIX lo define así y define el patrón como una expresión regular: un pequeño lenguaje donde un acento circunflejo significa «inicio de línea», una barra vertical «o bien», los corchetes «cualquiera de estos caracteres» y un más «una o más veces lo anterior». La opción de inversión da la vuelta a la prueba e imprime las líneas que no coinciden. La idea tiene unos cuarenta años y sigue siendo la vía más rápida para responder a una pregunta sobre un archivo de registro.

filter-lines implementa el bucle y la opción de inversión, y ahí se detiene. El lenguaje de patrones no está implementado, y sobre todo no lo está a medias: el término que escribes se compara como una secuencia de caracteres, entera y sin cambios. Es un diseño legítimo para un cuadro en una página web —la mayoría de quien filtra una lista quiere las líneas que contienen la palabra factura, no una gramática—, pero significa que las dos herramientas toman la misma entrada y dan respuestas distintas, y la que se equivoca nunca lo dice.

El cuadro vacío, y por qué está vacío

Se pasaron tres patrones por el mismo registro de siete líneas. ^ERROR no devolvió nada, aunque dos líneas empiezan por ERROR, porque ninguna línea contiene un acento circunflejo literal seguido de las letras E, R, R, O, R. ERROR|WARN no devolvió nada, aunque el registro tiene uno de cada, porque ninguna línea contiene una barra vertical literal entre esas dos palabras. [a-z]+ no devolvió nada, por lo mismo: ninguna línea contiene un corchete. En todos los casos el panel de salida estaba simplemente vacío. Nada se resaltó, nada se informó y nada sugirió que el término se hubiera leído de otra manera que la pretendida.

Este es el modo de fallo que importa, y es el inverso del que sugeriría la expresión «regex inválida». Un patrón malformado es el caso seguro. Escribir un simple paréntesis de apertura —lo que haría que un motor de expresiones regulares lanzara un error de grupo sin cerrar— conservó la línea que contiene un paréntesis y la devolvió. Lo mismo con un punto suelto, que en el lenguaje de las expresiones regulares significa «cualquier carácter» y aquí significa «un punto»: sobre una lista con a.b y aXb devolvió solo a.b. Si te sorprendes escribiendo sintaxis de expresión regular en este cuadro, el reflejo que hay que construir es mirar la salida y preguntarte si un resultado vacío es plausible, porque la herramienta no se lo preguntará por ti.

Caja, acentos y el espacio que no querías escribir

«Ignorar mayúsculas» está activo de fábrica y pone en minúsculas tanto la línea como el término antes de comparar. Filtrar una lista de cinco frutas por apple conservó apple pie, APPLE juice y pineapple tart; apagar el interruptor descartó APPLE juice y conservó las otras dos. La línea de pineapple recuerda que esto es una prueba de subcadena y no de palabra: apple está dentro de pineapple, así que la línea coincide, y no hay opción de «palabra entera» que lo impida. Si necesitas límites de palabra, añade los espacios alrededor de tu término y acepta que se te escapará la palabra al principio o al final de una línea.

De las mismas pruebas salieron dos trampas menores. Un espacio al principio del término forma parte del término: filtrar la misma lista por «espacio + apple» no devolvió nada, porque ninguna línea tiene un espacio delante de esa palabra en la posición probada. Y los acentos siguen la regla del artículo sobre duplicados: un término cuya letra acentuada se escribe como letra más marca combinante no encontró nada en una lista cuya letra acentuada es un solo punto de código, aunque las dos parezcan idénticas en el cuadro de búsqueda. Ambas vuelven a la misma disciplina: lo que escribiste se compara exactamente como lo escribiste, incluidas las partes que no ves.

El modo eliminar deja huecos

Cambia la acción a «Eliminar líneas coincidentes» y la herramienta descarta cada línea que contiene tu término y conserva todo lo demás, incluidas las líneas vacías, porque una línea vacía no contiene tu término. Pásalo por un registro con una línea vacía entre dos entradas y la línea vacía sigue ahí después. No es un fallo, es la lectura honesta de la instrucción, pero el resultado rara vez se parece a lo esperado, y un archivo filtrado con una docena de huecos huérfanos es molesto de leer. El arreglo es un paso más: pasa remove-blank-lines por la salida.

Un comportamiento más en el que apoyarse: un término vacío devuelve tu texto sin cambios, no un resultado vacío. Suena obvio, pero la lectura contraria —sin término, nada coincide, nada sale— sería igual de defendible y vaciaría en silencio tu entrada cada vez que borres el campo para escribir otra búsqueda. La herramienta toma la rama más segura, y se comprobó: con el campo vacío, volvieron las cinco líneas de la lista de prueba.

Qué hacer cuando de verdad necesitas un patrón

La mayoría de las preguntas de patrón se pueden reescribir como preguntas de subcadena. «Líneas que empiezan por un código» pasa a «líneas que contienen ese código», más laxo pero normalmente suficiente en un registro donde el código solo aparece al principio de todos modos. «Cualquiera de dos palabras» pasa a dos pasadas —filtra por la primera, anota el resultado, filtra el original por la segunda—, porque no hay alternancia. «Un rango de caracteres» suele pasar a varias pasadas o directamente a otra herramienta. Cuando la respuesta necesita de verdad una gramática, el consejo honesto es que un cuadro de texto en un navegador es el instrumento equivocado, y el bueno es un terminal o un editor de texto con búsqueda por expresión regular.

Una salvedad sobre la herramienta hermana. find-and-replace, en este mismo sitio, también toma un término literal: escapa cada carácter con significado especial antes de construir su patrón, cosa leída en su código y confirmada. Así que si esperabas usarla para simular un filtro por expresión regular, no puedes. Las dos herramientas son coherentes entre sí, esa es la buena noticia; ninguna de las dos es grep, esa es la noticia que necesitabas antes de empezar.

Términos escritos en el campo «Contiene», y lo que la herramienta devolvió realmente
Término escritoQué vuelvePor qué
apple, «Ignorar mayúsculas» activo (por defecto)apple pie, APPLE juice y pineapple tartAmbos lados se ponen en minúsculas, y la prueba es de subcadena, no de palabra entera
apple, «Ignorar mayúsculas» apagadosolo apple pie y pineapple tartAPPLE juice ya no contiene los caracteres exactos escritos
^ERROR sobre un registro cuyas dos primeras líneas empiezan por ERRORSalida vacía, ningún mensaje de errorNinguna línea contiene un acento circunflejo literal seguido de esas cinco letras
ERROR|WARN sobre el mismo registroSalida vacíaNo hay alternancia; la barra vertical es solo un carácter que buscar
Un simple paréntesis de aperturaLa línea que contiene un paréntesis — funcionaUna expresión regular inválida es el caso seguro, porque no se compila ninguna
Un punto suelto, sobre una lista con a.b y aXbsolo a.bEl punto coincide con un punto, no con cualquier carácter
Un campo «Contiene» vacíoEl texto entero, sin cambiosLa herramienta sale antes en vez de filtrarlo todo
Cualquier término, en modo «Eliminar líneas coincidentes», sobre un texto con líneas vacíasLas líneas vacías sobrevivenUna línea vacía no contiene el término, así que no es una coincidencia que eliminar
Filtrar líneasConserva o elimina las líneas que contienen una palabra o frase.Probar la herramienta

Preguntas frecuentes

¿Puedo usar una expresión regular en el campo «Contiene»?
No. El término se compara literalmente, carácter a carácter, sin lenguaje de patrones detrás. Se comprobó con tres patrones corrientes —un ancla de inicio de línea, una alternancia y una clase de caracteres— y los tres devolvieron un panel de salida vacío sin mensaje. El comportamiento que hay que interiorizar es que aquí una respuesta equivocada se parece exactamente a una respuesta correcta de «no coincidió nada», así que trata un resultado vacío como una pregunta y no como un hecho: reescribe el término sin sus caracteres de sintaxis y mira si aparecen líneas.
¿Cómo conservo solo las líneas que empiezan por algo?
Aquí no puedes pedir «inicio de línea», porque no hay ancla. En la práctica la versión de subcadena suele bastar: filtra por el código o prefijo en sí, y acepta las líneas que lo contengan en otro sitio. Si eso es aceptable depende de tus datos, y puedes averiguarlo barato: filtra una vez, luego pasa el mismo término en modo eliminar y mira lo que salió. Si el montón eliminado no contiene nada que quisieras, la versión laxa valía. Si de verdad necesitas el ancla, un editor de texto con búsqueda por expresión regular es la herramienta.
¿El filtro distingue mayúsculas?
Por defecto no. «Ignorar mayúsculas» está activo al cargar la página, lo contrario del ajuste por defecto de grep y lo contrario de lo que espera quien usa el terminal a diario. Apágalo desde el mismo panel si necesitas la distinción: filtrar una lista de frutas por apple con el interruptor activo conservó una línea APPLE juice, y apagarlo descartó esa línea manteniendo las dos en minúsculas. El plegado es el simple, independiente del idioma: trata bien las mayúsculas acentuadas pero no hace nada especial para un idioma concreto.
¿Por qué mi salida filtrada tiene huecos?
Porque usaste «Eliminar líneas coincidentes» y tu texto tenía líneas vacías. Una línea vacía no contiene tu término, así que la herramienta la conserva, y se queda justo donde estaba, ahora rodeada del espacio que ocupaban las líneas quitadas. Pasar remove-blank-lines por el resultado las cierra todas de una vez. Si encadenas varios filtros, haz la limpieza de líneas vacías una sola vez al final y no después de cada paso, porque cada pasada de eliminación abrirá huecos nuevos.
¿La herramienta me dice cuántas líneas coincidieron?
No se muestra ningún recuento; obtienes las líneas coincidentes y nada más. Si necesitas el número, el camino más corto es pasar el resultado por un contador de líneas, o usar count-occurrences sobre el texto original con el mismo término, teniendo en cuenta que cuenta apariciones y que una misma línea puede contener tu término dos veces, así que los dos números pueden diferir legítimamente. Si lo que quieres es el recuento y no las líneas, count-occurrences es el mejor punto de partida.

Artículos que podrían interesarte

Todas las guías
GuíaBuscar y reemplazar: las trampas de las expresiones regulares, demostradas una a unaCodicioso contra perezoso sobre la misma cadena, el punto que se salta los saltos de línea, $& y $$ en el reemplazo, una regex /g reutilizada que se salta una fila en silencio, y por qué /i no sabe nada de la i turca. Cada fallo ejecutado en Node, con una rutina contar-y-luego-reemplazar que los atrapa.TutorialNumerar las líneas de un texto para una revisión entre varias personasLa 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.ExplicaciónLos emoji son más difíciles de lo que parecen: por qué «basta con quitarlos» no tiene respuesta en una líneaUn emoji visible puede valer un punto de código o catorce unidades UTF-16. Lanzamos tres expresiones regulares populares sobre una frase real y cada una falló de otra forma; una borró los dígitos. Aquí está el porqué, qué propiedad Unicode responde a qué pregunta, y la regla de grupos de grafemas que sí funciona.ExplicaciónDónde puede cortarse una línea: el algoritmo Unicode detrás de cada párrafo ajustado«Cortar en los espacios» falla en la mayoría de los sistemas de escritura. UAX #14 da a cada carácter una clase de corte de línea; buscamos las nuestras en Unicode 17.0.0 y ejecutamos una implementación conforme sobre espacios duros, guiones blandos, espacios de ancho cero, URL, japonés y tailandés.GuíaConvertir entre formatos de lista sin perder datos: las reglas de comillas que nadie leePasar de una lista con saltos de línea a una lista con comas es trivial hasta que un elemento contiene una coma. Las reglas de comillas de la RFC 4180, por qué un campo CSV puede contener un salto de línea, por qué las hojas de cálculo europeas usan el punto y coma, y qué le hace un elemento vacío a la ida y vuelta — cada caso ejecutado e impreso.GuíaLimpiar una lista pegada desde una hoja de cálculo o un PDFUn pegado arrastra caracteres que no se ven: espacios duros, guiones opcionales, espacios de ancho cero, tabulaciones y CRLF. Se pasaron cuatro herramientas de limpieza por cada uno, y usan tres definiciones distintas de espacio.

Herramientas relacionadas

Todo lo que sigue describe lo que hacen estas herramientas hoy, comprobado ejecutando sus propias transformaciones sobre las entradas exactas que aparecen en cada artículo, y no lo que una norma obligue a hacer a una herramienta de texto. El tratamiento del texto línea a línea no tiene una autoridad única: qué cuenta como espacio, si dos líneas acentuadas son o no la misma línea, y dónde termina una URL dentro de una frase se deciden de forma distinta en cada programa en el que pegues texto. Cuando una herramienta falla en un caso, se dice claramente en vez de esquivarlo. Antes de pasar nada de esto por una lista que no puedas volver a exportar, pásalo por una copia y compara el número de líneas en ambos extremos.

Fuentes

¿Has detectado un error en este artículo?