El comando Cortar no extrae campos correctamente en columnas alineadas

El comando Cortar no extrae campos correctamente en columnas alineadas

Tengo un archivo de texto en el cual debo cortar los campos 3,4,5 y 8:

219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 433 4587 Mitchell     Barbara  C 4541 Admin Asst      12-14-1995
219 433 3589 Olson        Timothy  H 4544 Supervisor      06-30-1983
219 433 4591 Moore        Sarah    H 4500 Dept Manager    08-01-1978
219 431 4527 Polk         John     S 4520 Accountant      09-22-1998
219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 432 1557 Harrison     James    M 4544 Supervisor      01-07-2000

Dado que el delimitador por defecto es tab el comando para extraer los campos sería:

cut -f 3,4,5,8 filename

La cuestión es que la salida es la misma que el contenido del archivo original. ¿Que está sucediendo aquí? ¿Por qué esto no funciona?

Respuesta1

No todos esos espacios entre las columnas parecen pestañas, por lo que cutno podrás hacer lo que deseas. Sugeriría usar awken su lugar. Es más flexible que cutcuando se analizan columnas de datos como lo que intenta lograr:

$ awk '{print $3,$4,$5,$8}' data.txt

Ejemplo

$ awk '{print $3,$4,$5,$8}' data.txt 
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor

También puedes espaciar la salida usando el columncomando:

$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567  Harrison  Joel     Accountant
4587  Mitchell  Barbara  Admin
3589  Olson     Timothy  Supervisor
4591  Moore     Sarah    Dept
4527  Polk      John     Accountant
4567  Harrison  Joel     Accountant
1557  Harrison  James    Supervisor

También puedes hacer todo usando just awky printf:

$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt 
4567    Harrison Joel           Accountant
4587    Mitchell Barbara        Admin
3589    Olson Timothy           Supervisor
4591    Moore Sarah             Dept
4527    Polk John               Accountant
4567    Harrison Joel           Accountant
1557    Harrison James          Supervisor

corte revisado

Los métodos anteriores funcionan bien, pero no manejan ninguna de las líneas donde hay espacios dentro del valor de una columna en particular. Por ejemplo, la línea con "Administrador de departamento" se corta a solo Departamento.

Si se puede garantizar que los datos sean estructuras como las que se muestran, podríamos usarlas, cutpero en lugar de dividirlas según un delimitador, podríamos simplemente mostrarlas usando las posiciones reales de los caracteres.

Ejemplo

Esto cortará el texto del data.txtarchivo e imprimirá lo que esté en las posiciones 9 a 13 y 14 a 35, etc.

$ cut -c 9-13,14-35,43-58 data.txt 
4567 Harrison     Joel     Accountant      
4587 Mitchell     Barbara  Admin Asst      
3589 Olson        Timothy  Supervisor      
4591 Moore        Sarah    Dept Manager    
4527 Polk         John     Accountant      
4567 Harrison     Joel     Accountant      
1557 Harrison     James    Supervisor      

awk revisitado

También se puede hacer que Awk extraiga texto según su posición en lugar de mediante un delimitador. Sin embargo, es más detallado, pero aquí se explica cómo, solo para completar.

$ awk '{
    printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
  }' data.txt
4567    Harrison     Joel       Accountant      
4587    Mitchell     Barbara    Admin Asst      
3589    Olson        Timothy    Supervisor      
4591    Moore        Sarah      Dept Manager    
4527    Polk         John       Accountant      
4567    Harrison     Joel       Accountant      
1557    Harrison     James      Supervisor      

awk ANCHOS DE CAMPO

Si está utilizando una variante de GNU, awkpuede utilizar la variable FIELDWIDTHSpara especificar el tamaño estático de cada campo. Esto resulta ser mucho más limpio que el substrmétodo, si tienes acceso a él. También puede unir de manera efectiva campos que de otro modo se analizarían como campos separados.

$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt 
4567  Harrison     Joel     M  4540  Accountant      
4587  Mitchell     Barbara  C  4541  Admin Asst      
3589  Olson        Timothy  H  4544  Supervisor      
4591  Moore        Sarah    H  4500  Dept Manager    
4527  Polk         John     S  4520  Accountant      
4567  Harrison     Joel     M  4540  Accountant      
1557  Harrison     James    M  4544  Supervisor      

Respuesta2

Supongo que no creo que sean pestañas. La razón por la que no creo que sean pestañas es porque cuando copio y pego el archivo y tabulo manualmente los campos, parece cut -f 3,4,5,8 filenamefuncionar bien. Quizás sea mejor que lo haga cat filename | awk '{print $3, $4, $5, $8}'si no desea volver a tabular campos y valores.

información relacionada