GNU/Linux >> Tutoriales Linux >  >> Linux

4 Uso esencial y práctico del comando Cut en Linux

El comando de corte es la herramienta canónica para eliminar "columnas" de un archivo de texto. En este contexto, una “columna” se puede definir como un rango de caracteres o bytes identificados por su posición física en la línea, o un rango de campos delimitados por un separador.

He escrito sobre el uso de comandos AWK anteriormente. En esta guía detallada, explicaré cuatro ejemplos esenciales y prácticos del comando de corte en Linux que te serán de gran ayuda.

4 Ejemplos practicos del comando Cortar en Linux

Si lo prefiere, puede ver este video que explica los mismos ejemplos prácticos de comando de corte que he enumerado en el artículo.

1. Trabajando con rangos de caracteres

Cuando se invoca con -c opción de línea de comando, el comando de corte eliminará carácter rangos.

Como cualquier otro filtro, el comando de corte no cambia el archivo de entrada pero copiará los datos modificados a su salida estándar. Es su responsabilidad redirigir la salida del comando a un archivo para guardar el resultado o usar una canalización para enviarlo como entrada a otro comando.

Si ha descargado los archivos de prueba de muestra utilizados en el video anterior, puede ver el BALANCE.txt archivo de datos, que proviene directamente de un software de contabilidad que mi esposa usa en su trabajo:

sh$ head BALANCE.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNEENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNEENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNEENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNEENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNEENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNEENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

Este es un archivo de texto de ancho fijo ya que los campos de datos se rellenan con un número variable de espacios para garantizar que se muestren como una tabla bien alineada.

Como corolario, una columna de datos siempre comienza y termina en la misma posición de carácter en cada línea. Sin embargo, hay un pequeño escollo:a pesar de su nombre, el cut El comando en realidad requiere que especifique el rango de datos que desea conservar , no el intervalo que desea eliminar . Entonces, si necesito solo el ACCOUNTNUM y ACCOUNTLIB columnas en el archivo de datos anterior, escribiría eso:

sh$ cut -c 25-59 BALANCE.txt | head
ACCOUNTNUM ACCOUNTLIB
623477     TIDE SCHEDULE
445452     VAT BS/ENC
4356       /accountPAYABLES
623372     ACCOMODATION GUIDE
445452     VAT BS/ENC
4356       PAYABLES
4356       PAYABLES
445452     VAT BS/ENC
623795     TOURIST GUIDE BOOK

¿Qué es un rango?

Como acabamos de ver, el comando de corte requiere que especifiquemos el rango de datos que queremos conservar. Entonces, introduzcamos más formalmente qué es un rango:para el cut comando, un rango se define por una posición inicial y final separadas por un guión. Los rangos se basan en 1, es decir, el primer elemento de la línea es el elemento número 1, no 0. Los rangos son inclusivos:el inicio y el final se conservarán en la salida, así como todos los caracteres entre ellos. Es un error especificar un rango cuya posición final está antes ("inferior") que su posición inicial. Como atajo, puede omitir el inicio o valor final como se describe en la siguiente tabla:

  • a-b :el rango entre a y b (inclusive)
  • a :equivalente al rango a-a
  • -b :equivalente a 1-a
  • b- :equivalente a b-∞

Los comandos de corte le permiten especificar varios rangos separándolos con una coma. Aquí hay un par de ejemplos:

# Keep characters from 1 to 24 (inclusive)
cut -c -24 BALANCE.txt

# Keep characters from 1 to 24 and 36 to 59 (inclusive)
cut -c -24,36-59 BALANCE.txt

# Keep characters from 1 to 24, 36 to 59 and 93 to the end of the line (inclusive)
cut -c -24,36-59,93- BALANCE.txt

Una limitación (o característica, según se mire) del cut comando es que nunca reordenará los datos . Entonces, el siguiente comando producirá exactamente el mismo resultado que el anterior, a pesar de que los rangos se especifican en un orden diferente:

cut -c 93-,-24,36-59 BALANCE.txt

Puede verificar eso fácilmente usando el diff comando:

diff -s <(cut -c -24,36-59,93- BALANCE.txt) \
              <(cut -c 93-,-24,36-59 BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Del mismo modo, el cut comando nunca duplica datos :

# One might expect that could be a way to repeat
# the first column three times, but no...
cut -c -10,-10,-10 BALANCE.txt | head -5
ACCDOC
4
4
4
5

Vale la pena mencionar que hubo una propuesta para un -o opción de levantar esas dos últimas limitaciones, permitiendo el cut utilidad para reordenar o duplicar datos. Pero esto fue rechazado por el comité POSIX"porque este tipo de mejora está fuera del alcance del borrador del estándar IEEE P1003.2b".

Por mi parte, no conozco ninguna versión cortada que implemente esa propuesta como una extensión. Pero si lo hace, por favor, ¡compártalo con nosotros usando la sección de comentarios!

2. Trabajando con rangos de bytes

Cuando se invoca con -b opción de línea de comando, el comando de corte eliminará byte rangos.

A primera vista, no hay una diferencia obvia entre personaje y byte rangos:

sh$ diff -s <(cut -b -24,36-59,93- BALANCE.txt) \
              <(cut -c -24,36-59,93- BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Esto se debe a que mi archivo de datos de muestra usa la codificación de caracteres US-ASCII ("juego de caracteres") como file -i comando puede adivinarlo correctamente:

sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-ascii

En esa codificación de caracteres, hay un mapeo uno a uno entre caracteres y bytes. Usando solo un byte, teóricamente puede codificar hasta 256 caracteres diferentes (dígitos, letras, signos de puntuación, símbolos, etc.). generalmente encontrado). De todos modos, incluso si pudiéramos usar el rango de bytes completo, eso estaría lejos de ser suficiente para almacenar la variedad de escritura humana. Entonces, hoy en día, el mapeo uno a uno entre caracteres y bytes es más la excepción que la norma y casi siempre se reemplaza por la omnipresente codificación multibyte UTF-8. Veamos ahora cómo el comando de corte podría manejar eso.

Trabajando con caracteres multibyte

Como dije anteriormente, los archivos de datos de muestra utilizados como ejemplos para ese artículo provienen de un software de contabilidad utilizado por mi esposa. Agrega que actualizó ese software recientemente y, después de eso, los archivos de texto exportados fueron sutilmente diferentes. Te dejo que intentes encontrar la diferencia por ti mismo:

sh$ head BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNÉENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNÉENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNÉENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNÉENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNÉENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

El título de esta sección puede ayudarlo a encontrar lo que ha cambiado. Pero, encontrado o no, veamos ahora las consecuencias de ese cambio:

sh$ cut -c 93-,-24,36-59 BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

He copiado arriba la salida del comando in-extenso por lo que debería ser obvio que algo salió mal con la alineación de la columna.

La explicación es que el archivo de datos original contenía solo caracteres US-ASCII (símbolos, puntuaciones, números y letras latinas sin marcas diacríticas)

Pero si observa detenidamente el archivo producido después de la actualización del software, puede ver que el nuevo archivo de datos de exportación ahora conserva las letras acentuadas. Por ejemplo, la empresa denominada "ALNÉENRE" ahora está correctamente escrita mientras que anteriormente se exportaba como "ALNEENRE" (sin acento)

El archivo file -i La utilidad no se perdió ese cambio ya que ahora informa que el archivo está codificado en UTF-8:

sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8

Para ver cómo se codifican las letras acentuadas en un archivo UTF-8, podemos usar el hexdump utilidad que nos permite mirar directamente los bytes en un archivo:

# To reduce clutter, let's focus only on the second line of the file
sh$ sed '2!d' BALANCE-V2.txt
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
sh$ sed '2!d' BALANCE-V2.txt  | hexdump -C
00000000  34 20 20 20 20 20 20 20  20 20 31 30 31 32 30 31  |4         101201|
00000010  37 20 20 20 20 20 20 20  36 32 33 34 37 37 20 20  |7       623477  |
00000020  20 20 20 54 49 44 45 20  53 43 48 45 44 55 4c 45  |   TIDE SCHEDULE|
00000030  20 20 20 20 20 20 20 20  20 20 20 41 4c 4e c3 89  |           ALN..|
00000040  45 4e 52 45 2d 34 37 30  31 2d 4c 4f 43 20 20 20  |ENRE-4701-LOC   |
00000050  20 20 20 20 20 20 20 20  20 20 20 20 20 30 30 30  |             000|
00000060  30 30 30 30 31 36 31 35  2c 30 30 20 20 20 20 20  |00001615,00     |
00000070  20 20 20 20 20 20 20 20  20 20 20 0a              |           .|
0000007c

En la línea 00000030 del hexdump salida, después de un montón de espacios (byte 20 ), puedes ver:

  • la letra A está codificado como el byte 41 ,
  • la letra L está codificado en el byte 4c ,
  • y la letra N está codificado como el byte 4e .

Pero, la LETRA E MAYÚSCULA LATINA MAYÚSCULA CON AGUDA (ya que es el nombre oficial de la letra É en el estándar Unicode) se codifica con dos bytes c3 89

Y aquí está el problema:usar el cut El comando con rangos expresados ​​como posiciones de bytes funciona bien para codificaciones de longitud fija, pero no para codificaciones de longitud variable como UTF-8 o Shift JIS. Esto se explica claramente en el siguiente extracto no normativo del estándar POSIX:

Las versiones anteriores de la utilidad de corte funcionaban en un entorno en el que los bytes y los caracteres se consideraban equivalentes (procesamiento de módulo y en algunas implementaciones). En el mundo extendido de los caracteres de varios bytes, se ha agregado la nueva opción -b.

¡Oye, espera un minuto! No estaba usando -b opción en el ejemplo "defectuoso" anterior, pero el -c opción. Entonces, no debería que han funcionado?!?

Sí, debería :es lamentable, pero estamos en 2018 y, a pesar de eso, a partir de GNU Coreutils 8.30, la implementación de GNU de la utilidad de corte todavía no maneja correctamente los caracteres de varios bytes. Para citar la documentación de GNU, el -c la opción es “Lo mismo que -b por ahora, pero la internacionalización cambiará eso[… ]” — ¡una mención que está presente desde hace más de 10 años!

Por otro lado, la implementación de OpenBSD de la utilidad de corte es compatible con POSIX y respetará la configuración local actual para manejar correctamente los caracteres de varios bytes:

# Ensure subseauent commands will know we are using UTF-8 encoded
# text files
openbsd-6.3$ export LC_CTYPE=en_US.UTF-8

# With the `-c` option, cut works properly with multi-byte characters
openbsd-6.3$ cut -c -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE           00000001615,00
4         1012017       VAT BS/ENC              00000000323,00
4         1012017       PAYABLES                               00000001938,00
5         1012017       ACCOMODATION GUIDE      00000001333,00
5         1012017       VAT BS/ENC              00000000266,60
5         1012017       PAYABLES                               00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                               00000000240,00
31        1012017       VAT BS/DEBIT            00000000040,00
31        1012017       ADVERTISEMENTS          00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE      00000000069,14
36        1012017       VAT BS/ENC              00000000013,83

Como era de esperar, al usar -b modo byte en lugar de -c modo de caracteres, la implementación de corte de OpenBSD se comporta como el cut heredado :

openbsd-6.3$ cut -b -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

3. Trabajando con campos

En cierto sentido, trabajar con campos en un archivo de texto delimitado es más fácil para el cut utilidad, ya que solo tendrá que ubicar los delimitadores de campo (un byte) en cada fila, copiando luego palabra por palabra el contenido del campo en la salida sin preocuparse por ningún problema de codificación.

Aquí hay un archivo de texto delimitado de muestra:

sh$ head BALANCE.csv
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;ACCDOCLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;ALNEENRE-4701-LOC;00000001615,00;
4;1012017;445452;VAT BS/ENC;ALNEENRE-4701-LOC;00000000323,00;
4;1012017;4356;PAYABLES;ALNEENRE-4701-LOC;;00000001938,00
5;1012017;623372;ACCOMODATION GUIDE;ALNEENRE-4771-LOC;00000001333,00;
5;1012017;445452;VAT BS/ENC;ALNEENRE-4771-LOC;00000000266,60;
5;1012017;4356;PAYABLES;ALNEENRE-4771-LOC;;00000001599,60
6;1012017;4356;PAYABLES;FACT FA00006253 - BIT QUIROBEN;;00000001837,20
6;1012017;445452;VAT BS/ENC;FACT FA00006253 - BIT QUIROBEN;00000000306,20;
6;1012017;623795;TOURIST GUIDE BOOK;FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Es posible que conozca ese formato de archivo como CSV (por valor separado por comas), incluso si el separador de campo no siempre es una coma. Por ejemplo, el punto y coma (; ) se encuentra con frecuencia como un separador de campo, y a menudo es la opción predeterminada al exportar datos como "CSV" en países que ya usan la coma como separador decimal (como lo hacemos en Francia; de ahí la elección de ese carácter en mi archivo de muestra ). Otra variante popular utiliza un carácter de tabulación como separador de campo, produciendo lo que a veces se denomina un archivo de valores separados por tabulaciones. Finalmente, en el mundo de Unix y Linux, los dos puntos (: ) es otro separador de campo relativamente común que puede encontrar, por ejemplo, en el estándar /etc/passwd y /etc/group archivos.

Cuando usa un formato de archivo de texto delimitado, proporciona al comando de corte el rango de campos para seguir usando el -f opción, y debe especificar el delimitador usando -d opción (sin -d opción, la utilidad de corte tiene por defecto un carácter de tabulación para el separador):

sh$ cut -f 5- -d';' BALANCE.csv | head
ACCDOCLIB;DEBIT;CREDIT
ALNEENRE-4701-LOC;00000001615,00;
ALNEENRE-4701-LOC;00000000323,00;
ALNEENRE-4701-LOC;;00000001938,00
ALNEENRE-4771-LOC;00000001333,00;
ALNEENRE-4771-LOC;00000000266,60;
ALNEENRE-4771-LOC;;00000001599,60
FACT FA00006253 - BIT QUIROBEN;;00000001837,20
FACT FA00006253 - BIT QUIROBEN;00000000306,20;
FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Manejo de líneas que no contienen el delimitador

Pero, ¿qué pasa si alguna línea en el archivo de entrada no contiene el delimitador? Es tentador imaginar eso como una fila que contiene solo el primer campo. Pero esto no lo que hace la utilidad de corte.

Por defecto, cuando se usa -f opción, la utilidad de corte siempre generará una línea textual que no contiene el delimitador (probablemente asumiendo que se trata de una fila sin datos, como un encabezado o un comentario de algún tipo):

sh$ (echo "# 2018-03 BALANCE"; cat BALANCE.csv) > BALANCE-WITH-HEADER.csv

sh$ cut -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
# 2018-03 BALANCE
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00

Usando el -s opción, puede revertir ese comportamiento, así que cut siempre ignorará dicha línea:

sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;

Si está de humor para hackear, puede explotar esa función como una forma relativamente oscura de mantener solo las líneas que contienen un carácter determinado:

# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'

Cambiando el delimitador de salida

Como extensión, la implementación GNU de cut permite usar un separador de campo diferente para la salida usando el --output-delimiter opción:

sh$ cut -f 5,6- -d';' --output-delimiter="*" BALANCE.csv | head
ACCDOCLIB*DEBIT*CREDIT
ALNEENRE-4701-LOC*00000001615,00*
ALNEENRE-4701-LOC*00000000323,00*
ALNEENRE-4701-LOC**00000001938,00
ALNEENRE-4771-LOC*00000001333,00*
ALNEENRE-4771-LOC*00000000266,60*
ALNEENRE-4771-LOC**00000001599,60
FACT FA00006253 - BIT QUIROBEN**00000001837,20
FACT FA00006253 - BIT QUIROBEN*00000000306,20*
FACT FA00006253 - BIT QUIROBEN*00000001531,00*

Observe, en ese caso, todas las apariciones del separador de campo se reemplazan, y no solo aquellas en el límite de los rangos especificados en los argumentos de la línea de comando.

4. Extensiones GNU no POSIX

Hablando de extensiones GNU no POSIX, un par de ellas que pueden ser particularmente útiles. Vale la pena mencionar que las siguientes extensiones funcionan igual de bien con bytes, caracteres (para lo que eso significa en la implementación actual de GNU) o rangos de campo:--complement

Piense en esa opción como el signo de exclamación en una dirección sed (! ); en lugar de mantener los datos que coinciden con el rango dado, cut mantendrá los datos que NO coincidan con el rango

# Keep only field 5
sh$ cut -f 5 -d';' BALANCE.csv |head -3
ACCDOCLIB
ALNEENRE-4701-LOC
ALNEENRE-4701-LOC

# Keep all but field 5
sh$ cut --complement -f 5 -d';' BALANCE.csv |head -3
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;00000001615,00;
4;1012017;445452;VAT BS/ENC;00000000323,00;

--zero-terminated (-z )

utilice el carácter NUL como terminador de línea en lugar del carácter de nueva línea. El -z La opción es particularmente útil cuando sus datos pueden contener caracteres de nueva línea incrustados, como cuando se trabaja con nombres de archivo (dado que la nueva línea es un carácter válido en un nombre de archivo, pero NUL no lo es).

Para mostrarle cómo -z la opción funciona, hagamos un pequeño experimento. Primero, crearemos un archivo cuyo nombre contenga nuevas líneas incrustadas:

bash$ touch

Supongamos ahora que quiero mostrar los primeros 5 caracteres de cada *.txt nombre del archivo. Una solución ingenua fallará miserablemente aquí:

sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.

Es posible que ya hayas leído ls fue diseñado para el consumo humano, y usarlo en una canalización de comando es un antipatrón (de hecho lo es). Así que usemos el find comando en su lugar:

sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALAN

y... que produjo básicamente el mismo resultado erróneo que antes (aunque en un orden diferente porque ls ordena implícitamente los nombres de archivo, algo que find el comando no funciona).

El problema es en ambos casos, el cut El comando no puede hacer la distinción entre un carácter de nueva línea que forma parte de un campo de datos (el nombre de archivo) y un carácter de nueva línea utilizado como marcador de fin de registro. Pero, usando el byte NUL (\0 ) a medida que el terminador de línea aclara la confusión para que finalmente podamos obtener el resultado esperado:

# I was told (?) some old versions of tr require using \000 instead of \0
# to denote the NUL character (let me know if you needed that change!)
sh$ find . -name '*.txt' -printf "%f\0" | cut -z -c 1-5| tr '\0' '\n'
BALAN
EMPTY
BALAN

Con ese último ejemplo, nos estamos alejando del núcleo de este artículo que era el cut dominio. Entonces, dejaré que trates de averiguar por ti mismo el significado del funky "%f\0" después de -printf argumento del find comando o por qué usé el tr comando al final de la canalización.

Se puede hacer mucho más con el comando Cortar

Acabo de mostrar el uso más común y, en mi opinión, el más esencial del comando Cortar. Puede aplicar el comando de formas aún más prácticas. Depende de tu razonamiento lógico e imaginación.

No dude en utilizar la sección de comentarios a continuación para publicar sus hallazgos. Y, como siempre, si te gusta este artículo, ¡no olvides compartirlo en tus sitios web y redes sociales favoritos!


Linux
  1. Comando Cat de Linux:uso y ejemplos

  2. El comando Sed de Linux:uso y ejemplos

  3. Comandos de Linux:trabajos, bg y fg

  4. El comando AWK de Linux:ejemplos de sintaxis de uso de Linux y Unix

  5. Comando df de Linux

50 comandos de corte de Linux simples y útiles en Unix con ejemplos

40 Comando awk práctico y útil en Linux y BSD

50 comandos grep productivos y prácticos para entusiastas de Linux

16 Ejemplos Prácticos y Útiles del Comando Echo en Linux

7 Uso esencial y práctico del comando Pegar en Linux

Cat Command en Linux:ejemplos esenciales y avanzados