Buscar..


Introducción

El comando de cut es una forma rápida de extraer partes de líneas de archivos de texto. Pertenece a los comandos más antiguos de Unix. Sus implementaciones más populares son la versión GNU que se encuentra en Linux y la versión FreeBSD que se encuentra en MacOS, pero cada versión de Unix tiene la suya. Vea a continuación las diferencias. Las líneas de entrada se leen desde la stdin o desde los archivos enumerados como argumentos en la línea de comando.

Sintaxis

  • cortar -f1,3 # extraer el primer y tercer campo delimitado por tabuladores (desde stdin)

  • cortar -f1-3 # extraer desde el primer hasta el tercer campo (extremos incluidos)

  • corte -f-3 # -3 se interpreta como 1-3

  • cut -f2- # 2- se interpreta desde el segundo hasta el último

  • cortar -c1-5,10 # extraer de stdin los caracteres en las posiciones 1,2,3,4,5,10

  • cut -s -f1 # suprimir líneas que no contienen delimitadores

  • corte --complemento -f3 # (solo corte GNU) extraiga todos los campos excepto el tercero

Parámetros

Parámetro Detalles
-f, - campos Selección basada en el campo
-d, --delimitador Delimitador para selección de campo
-c, --caracteres Selección basada en caracteres, delimitador ignorado o error
-s, - solo delimitado Suprimir líneas sin caracteres delimitadores (impresos como están).
--complemento Selección invertida (extraer todos los campos / caracteres excepto los especificados
- salida-delimitador Especifique cuándo debe ser diferente del delimitador de entrada.

Observaciones

1. Diferencias de sintaxis.

Las opciones largas en la tabla anterior solo son compatibles con la versión GNU.

2. Ningún personaje recibe tratamiento especial.

El cut FreeBSD (que viene con MacOS, por ejemplo) no tiene el interruptor --complement y, en el caso de los rangos de caracteres, se puede usar el comando colrm lugar:

  $ cut --complement -c3-5 <<<"123456789"
  126789

  $ colrm 3 5 <<<"123456789"
  126789

Sin embargo, hay una gran diferencia, porque colrm trata los caracteres TAB (ASCII 9) como tabulaciones reales hasta el siguiente múltiplo de ocho, y los espacios en blanco (ASCII 8) como -1 de ancho; por el contrario, cut trata a todos los caracteres como una columna de ancho.

  $ colrm  3 8 <<<$'12\tABCDEF' # Input string has an embedded TAB
  12ABCDEF

  $ cut --complement -c3-8 <<<$'12\tABCDEF'
  12F

3. (Todavía no) Internacionalización

Cuando se diseñó el cut , todos los caracteres tenían un byte de largo y la internacionalización no era un problema. Cuando los sistemas de escritura con caracteres más anchos se hicieron populares, la solución adoptada por POSIX fue diferenciar entre el viejo conmutador -c , que debería conservar su significado de seleccionar caracteres, sin importar cuántos bytes de ancho, e introducir un nuevo conmutador -b que debería Seleccione bytes, independientemente de la codificación de caracteres actual. En las implementaciones más populares, se introdujo -b y funciona, pero -c sigue funcionando exactamente igual que -b y no como debería. Por ejemplo, con cut GNU:

Parece que el filtro de correo no deseado de SE incluye listas negras de textos en inglés con caracteres kanji aislados. No pude superar esta limitación, por lo que los siguientes ejemplos son menos expresivos de lo que podrían ser.

  # In an encoding where each character in the input string is three bytes wide,
  # Selecting bytes 1-6 yields the first two characters (correct)
  $ LC_ALL=ja_JP.UTF-8 cut -b1-6 kanji.utf-8.txt
  ...first two characters of each line...
  

  # Selecting all three characters with the -c switch doesn’t work.
  # It behaves like -b, contrary to documentation.
  $ LC_ALL=ja_JP.UTF-8 cut -c1-3 kanji.utf-8.txt
  ...first character of each line...

  # In this case, an illegal UTF-8 string is produced.
  # The -n switch would prevent this, if implemented.
  $ LC_ALL=ja_JP.UTF-8 cut -n -c2 kanji.utf-8.txt
  ...second byte, which is an illegal UTF-8 sequence...

Si sus caracteres están fuera del rango ASCII y desea utilizar el cut , siempre debe tener en cuenta el ancho de caracteres en su codificación y utilizar -b consecuencia. Si y cuando -c comienza a funcionar como se documenta, no tendrá que cambiar sus scripts.

4. Comparaciones de velocidad.

Las limitaciones del cut hacen que las personas duden de su utilidad. De hecho, la misma funcionalidad se puede lograr mediante utilidades más potentes y populares. Sin embargo, la ventaja del cut es su rendimiento . Vea a continuación para algunas comparaciones de velocidad. test.txt tiene tres millones de líneas, con cinco campos separados por espacios. Para la prueba awk , se usó mawk , porque es más rápido que GNU awk . El shell en sí (última línea) es, con mucho, el peor desempeño. Los tiempos dados (en segundos) son lo que el comando de time da como tiempo real .

(Solo para evitar malentendidos: todos los comandos probados dieron la misma salida con la entrada dada, pero por supuesto no son equivalentes y darían salidas diferentes en diferentes situaciones, en particular si los campos estuvieran delimitados por un número variable de espacios)

Mando Hora
cut -d ' ' -f1,2 test.txt 1.138s
awk '{print $1 $2}' test.txt 1.688s
join -a1 -o1.1,1.2 test.txt /dev/null 1.767s
perl -lane 'print "@F[1,2]"' test.txt 11.390s
grep -o '^\([^ ]*\) \([^ ]*\)' test.txt 22.925s
sed -e 's/^\([^ ]*\) \([^ ]*\).*$/\1 \2/' test.txt 52.122s
while read ab _; do echo $a $b; done <test.txt 55.582s

5. Páginas de manual referenciales

Uso básico

El uso típico es con archivos de tipo CSV, donde cada línea consta de campos separados por un delimitador, especificados por la opción -d . El delimitador predeterminado es el carácter TAB. Supongamos que tiene un archivo de datos data.txt con líneas como

0 0 755 1482941948.8024
102 33 4755 1240562224.3205
1003 1 644 1219943831.2367

Entonces

# extract the third space-delimited field
$ cut -d ' ' -f3 data.txt
755
4755
644

# extract the second dot-delimited field
$ cut -d. -f2 data.txt    
8024
3205
2367

# extract the character range from the 20th through the 25th character
$ cut -c20-25 data.txt 
948.80
056222    
943831

Como de costumbre, puede haber espacios opcionales entre un interruptor y su parámetro: -d, es lo mismo que -d ,

GNU cut permite especificar una opción --output-delimiter : (una característica independiente de este ejemplo es que debe escaparse un punto y coma como delimitador de entrada para evitar su tratamiento especial por parte del shell)

$ cut --output-delimiter=, -d\; -f1,2 <<<"a;b;c;d"
a,b

Sólo un personaje delimitador.

No puede tener más de un delimitador: si especifica algo como -d ",;:" , algunas implementaciones usarán solo el primer carácter como delimitador (en este caso, la coma). Otras implementaciones (por ejemplo, cut GNU) darán un mensaje de error

$ cut -d ",;:" -f2 <<<"J.Smith,1 Main Road,cell:1234567890;land:4081234567"
cut: the delimiter must be a single character
Try `cut --help' for more information.

Los delimitadores repetidos se interpretan como campos vacíos

$ cut -d, -f1,3 <<<"a,,b,c,d,e"
a,b

es bastante obvio, pero con cadenas delimitadas por el espacio podría ser menos obvio para algunos

$ cut -d ' ' -f1,3 <<<"a  b c d e"
a b

cut no se puede usar para analizar argumentos como lo hace el shell y otros programas.

Sin citar

No hay forma de proteger el delimitador. Las hojas de cálculo y el software de manejo de CSV similar generalmente pueden reconocer un carácter de comillas de texto que hace posible definir cadenas que contienen un delimitador. Con el cut no puedes.

$ cut -d, -f3 <<<'John,Smith,"1, Main Street"'
"1

Extraer, no manipular.

Solo puede extraer partes de líneas, no reordenar o repetir campos.

$ cut -d, -f2,1 <<<'John,Smith,USA' ## Just like -f1,2
John,Smith
$ cut -d, -f2,2 <<<'John,Smith,USA' ## Just like -f2
Smith


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow