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 cut
no podrás hacer lo que deseas. Sugeriría usar awk
en su lugar. Es más flexible que cut
cuando 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 column
comando:
$ 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 awk
y 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, cut
pero 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.txt
archivo 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, awk
puede utilizar la variable FIELDWIDTHS
para especificar el tamaño estático de cada campo. Esto resulta ser mucho más limpio que el substr
mé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 filename
funcionar 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.