<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Línea De Comandos el josiete.com</title><link>https://www.josiete.com/tags/l%C3%ADnea-de-comandos/</link><description>Contenido reciente en Línea De Comandos el josiete.com</description><generator>Hugo</generator><language>es-es</language><lastBuildDate>Wed, 07 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.josiete.com/tags/l%C3%ADnea-de-comandos/index.xml" rel="self" type="application/rss+xml"/><item><title>csvkit: una caja de herramientas para trabajar con CSV desde la terminal</title><link>https://www.josiete.com/posts/csvkit/</link><pubDate>Wed, 07 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.josiete.com/posts/csvkit/</guid><description>&lt;p&gt;&lt;img src="https://www.josiete.com/images/csvkit.webp" alt="Ilustración de una terminal conectada a documentos CSV y tablas de datos mediante etapas de procesamiento"&gt;&lt;/p&gt;&#10;&lt;p&gt;Te llega un fichero CSV. Antes de cargarlo en una base de datos, quieres saber qué columnas tiene, si faltan valores y qué registros te interesan. Abrir una hoja de cálculo funciona, pero resulta poco cómodo cuando tienes que repetir la misma operación con varios archivos. Escribir un programa para cada comprobación tampoco siempre compensa.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://csvkit.readthedocs.io/en/latest/"&gt;csvkit&lt;/a&gt; reúne herramientas de línea de comandos para convertir y procesar datos tabulares. Está escrito en Python y permite resolver muchas de esas tareas con instrucciones breves que puedes guardar y ejecutar de nuevo.&lt;/p&gt;&#10;&lt;h2 id="un-csv-tiene-más-estructura-de-la-que-parece"&gt;Un CSV tiene más estructura de la que parece&lt;/h2&gt;&#10;&lt;p&gt;Separar una línea por comas puede parecer suficiente hasta que aparece un valor como &lt;code&gt;&amp;quot;Madrid, centro&amp;quot;&lt;/code&gt;. También puede haber comillas escapadas o saltos de línea dentro de un campo. Por eso, usar &lt;code&gt;cut&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt; o &lt;code&gt;sort&lt;/code&gt; directamente sobre el texto requiere cuidado: esas herramientas no interpretan por sí mismas la estructura de un CSV.&lt;/p&gt;&#10;&lt;p&gt;csvkit trabaja con filas y columnas. Puedes pedir una columna por su nombre, filtrar un campo concreto y encadenar operaciones mediante &lt;code&gt;|&lt;/code&gt;. La salida sigue siendo CSV en los comandos de transformación; &lt;code&gt;csvlook&lt;/code&gt;, en cambio, genera una tabla para leer en pantalla. El &lt;a href="https://csvkit.readthedocs.io/en/latest/tutorial/1_getting_started.html"&gt;tutorial oficial&lt;/a&gt; explica este uso de la entrada y salida estándar.&lt;/p&gt;&#10;&lt;h2 id="instalación"&gt;Instalación&lt;/h2&gt;&#10;&lt;p&gt;La documentación recomienda instalarlo en un entorno virtual. En Linux o macOS:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python3 -m venv .venv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source .venv/bin/activate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m pip install csvkit&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvcut --version&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En PowerShell, la activación se hace con &lt;code&gt;.venv\Scripts\Activate.ps1&lt;/code&gt;. La instalación incorpora varios ejecutables, como &lt;code&gt;csvcut&lt;/code&gt; y &lt;code&gt;csvstat&lt;/code&gt;: no hay que invocar un único comando llamado &lt;code&gt;csvkit&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="un-ejemplo-que-puedes-reproducir"&gt;Un ejemplo que puedes reproducir&lt;/h2&gt;&#10;&lt;p&gt;Guarda este contenido como &lt;code&gt;ventas.csv&lt;/code&gt;, en UTF-8:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csv" data-lang="csv"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;id&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;cliente&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;categoria&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;unidades&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;precio&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;estado&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;1&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;Librería Norte&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;libros&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;2&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;18.50&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;pagado&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;2&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;Café, Central&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;hogar&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;1&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;32.00&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;pendiente&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;3&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;Librería Norte&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;libros&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;3&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;12.00&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;pagado&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;4&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;Estudio Sur&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;hogar&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;2&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;25.00&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;pagado&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La coma en &lt;code&gt;&amp;quot;Café, Central&amp;quot;&lt;/code&gt; pertenece al nombre del cliente, no separa dos columnas.&lt;/p&gt;&#10;&lt;h3 id="inspeccionar-antes-de-transformar"&gt;Inspeccionar antes de transformar&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvcut -n ventas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvlook ventas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvstat ventas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvstat --count ventas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;csvcut -n&lt;/code&gt; enumera las columnas y &lt;code&gt;csvlook&lt;/code&gt; facilita la lectura. &lt;a href="https://csvkit.readthedocs.io/en/latest/scripts/csvstat.html"&gt;csvstat&lt;/a&gt; resume tipos inferidos, valores nulos y estadísticas según el tipo de cada columna. El último comando devuelve &lt;code&gt;4&lt;/code&gt;: cuenta registros, no líneas físicas del fichero. Esta distinción importa cuando los campos contienen saltos de línea.&lt;/p&gt;&#10;&lt;h3 id="elegir-columnas-y-filtrar-filas"&gt;Elegir columnas y filtrar filas&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvgrep -c estado -r &lt;span style="color:#e6db74"&gt;&amp;#39;^pagado$&amp;#39;&lt;/span&gt; ventas.csv &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; | csvcut -c cliente,categoria,unidades,precio &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;gt; ventas_pagadas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvsort -c precio -r ventas_pagadas.csv | csvlook&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://csvkit.readthedocs.io/en/latest/scripts/csvgrep.html"&gt;csvgrep&lt;/a&gt; aplica la expresión regular a la columna &lt;code&gt;estado&lt;/code&gt;. Las anclas &lt;code&gt;^&lt;/code&gt; y &lt;code&gt;$&lt;/code&gt; hacen que coincida con el contenido completo del campo. Después seleccionamos cuatro columnas y guardamos el resultado. &lt;code&gt;csvsort&lt;/code&gt; ordena por precio de mayor a menor; aquí los precios se interpretan como números.&lt;/p&gt;&#10;&lt;p&gt;La tubería conecta la salida de un comando con la entrada del siguiente. &lt;code&gt;&amp;gt;&lt;/code&gt; escribe esa salida en un fichero y sobrescribe su contenido si ya existe. Usa un nombre distinto al archivo de entrada para no truncarlo antes de leerlo.&lt;/p&gt;&#10;&lt;h3 id="agregar-con-sql"&gt;Agregar con SQL&lt;/h3&gt;&#10;&lt;p&gt;Para calcular el importe de las ventas pagadas por categoría:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvsql --query &lt;span style="color:#e6db74"&gt;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; SELECT categoria,&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; SUM(unidades * precio) AS importe&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; FROM ventas&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; WHERE estado = &amp;#39;pagado&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; GROUP BY categoria&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ORDER BY importe DESC&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; ventas.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado suma &lt;code&gt;73&lt;/code&gt; en libros y &lt;code&gt;50&lt;/code&gt; en hogar; su representación decimal puede variar. Por defecto, el nombre de la tabla procede del fichero sin su extensión: &lt;code&gt;ventas.csv&lt;/code&gt; se convierte en &lt;code&gt;ventas&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://csvkit.readthedocs.io/en/latest/scripts/csvsql.html"&gt;csvsql&lt;/a&gt; carga los datos en una base SQLite en memoria para ejecutar esta consulta. También permite generar sentencias SQL o importar datos en una base de datos. Para cálculos monetarios que exijan exactitud, conviene definir una estrategia de precisión: la ejecución SQL puede introducir efectos de coma flotante.&lt;/p&gt;&#10;&lt;h2 id="unir-archivos-y-cambiar-de-formato"&gt;Unir archivos y cambiar de formato&lt;/h2&gt;&#10;&lt;p&gt;Supongamos que &lt;code&gt;clientes.csv&lt;/code&gt; contiene:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csv" data-lang="csv"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;cliente&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;ciudad&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Librería Norte&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;Bilbao&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Café, Central&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;Madrid&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Estudio Sur&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;Sevilla&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Podemos añadir la ciudad a cada venta:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvjoin --left -c cliente ventas.csv clientes.csv &amp;gt; ventas_con_ciudad.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://csvkit.readthedocs.io/en/latest/scripts/csvjoin.html"&gt;csvjoin&lt;/a&gt; combina tablas por una clave. &lt;code&gt;--left&lt;/code&gt; conserva todas las filas del primer archivo, aunque no haya coincidencia en el segundo. Si una clave aparece varias veces en ambos archivos, la unión puede multiplicar las filas: comprueba que esa relación sea la que necesitas.&lt;/p&gt;&#10;&lt;p&gt;Para otras entradas y salidas:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;in2csv ventas.xlsx &amp;gt; ventas_desde_excel.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvjson ventas.csv &amp;gt; ventas.json&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvformat -D &lt;span style="color:#e6db74"&gt;&amp;#39;;&amp;#39;&lt;/span&gt; ventas.csv &amp;gt; ventas_punto_y_coma.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;in2csv&lt;/code&gt; convierte una hoja de Excel en datos tabulares; no preserva su presentación. &lt;code&gt;csvjson&lt;/code&gt; produce JSON y &lt;a href="https://csvkit.readthedocs.io/en/latest/scripts/csvformat.html"&gt;csvformat&lt;/a&gt; permite cambiar el delimitador de salida. Fíjate en la diferencia: &lt;code&gt;-d&lt;/code&gt; indica el separador de entrada y &lt;code&gt;-D&lt;/code&gt;, en &lt;code&gt;csvformat&lt;/code&gt;, el de salida.&lt;/p&gt;&#10;&lt;h2 id="separadores-codificaciones-y-tipos"&gt;Separadores, codificaciones y tipos&lt;/h2&gt;&#10;&lt;p&gt;Para un archivo separado por punto y coma y codificado en Windows-1252:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csvlook -d &lt;span style="color:#e6db74"&gt;&amp;#39;;&amp;#39;&lt;/span&gt; -e cp1252 -y &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; -I exportacion.csv&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;-y 0&lt;/code&gt; desactiva la detección automática del dialecto. &lt;code&gt;-I&lt;/code&gt; desactiva la inferencia de tipos en los comandos que la admiten, como &lt;code&gt;csvlook&lt;/code&gt;, &lt;code&gt;csvstat&lt;/code&gt; y &lt;code&gt;csvsql&lt;/code&gt;. Resulta útil para conservar como texto identificadores como &lt;code&gt;00123&lt;/code&gt;. Los &lt;a href="https://csvkit.readthedocs.io/en/latest/common_arguments.html"&gt;argumentos comunes&lt;/a&gt; documentan las opciones de codificación y formato; consulta también la ayuda del comando concreto.&lt;/p&gt;&#10;&lt;p&gt;No desactives la inferencia sin pensar en la siguiente operación: un precio tratado como texto puede ordenarse de forma distinta a un número. Y que un fichero se lea correctamente no demuestra que sus datos sean válidos; las reglas de negocio siguen necesitando comprobaciones propias.&lt;/p&gt;&#10;&lt;h2 id="cuándo-encaja-en-tu-trabajo"&gt;Cuándo encaja en tu trabajo&lt;/h2&gt;&#10;&lt;p&gt;csvkit resulta cómodo para explorar una exportación, preparar una carga o automatizar transformaciones pequeñas y repetibles. Puedes guardar los comandos en un script y revisar exactamente qué filtros aplicaste.&lt;/p&gt;&#10;&lt;p&gt;Cuando aumentan mucho el volumen o la complejidad, conviene evaluar un motor como &lt;a href="https://www.josiete.com/posts/duckdb/"&gt;DuckDB&lt;/a&gt; o una librería como &lt;a href="https://www.josiete.com/posts/polars-python/"&gt;Polars&lt;/a&gt;. Algunas operaciones de csvkit necesitan mantener datos en memoria y cada comando de una tubería puede volver a interpretarlos. Su principal atractivo es la comodidad: pasar de un CSV desconocido a una transformación comprensible con unas pocas instrucciones.&lt;/p&gt;&#10;</description></item></channel></rss>