Tenho um arquivo texto no qual devo recortar os campos 3,4,5 e 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
Como o delimitador por padrão é tab o comando para extrair os campos seria:
cut -f 3,4,5,8 filename
O problema é que a saída é igual ao conteúdo original do arquivo. O que esta acontecendo aqui? Por que isso não funciona?
Responder1
Nem todos os espaços entre as colunas parecem tabulações, portanto cut
não será possível fazer o que deseja. Eu sugiro usar awk
em vez disso. É mais flexível do que cut
analisar colunas de dados como o que você está tentando realizar:
$ awk '{print $3,$4,$5,$8}' data.txt
Exemplo
$ 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
Você também pode espaçar a saída usando o 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
Você também pode fazer tudo usando just awk
e 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 revisitado
Os métodos acima fazem um bom trabalho, mas não lidam com nenhuma das linhas onde há espaços dentro do valor de uma coluna específica. Por exemplo, a linha com "Dept Manager" foi reduzida para apenas Dept.
Se for possível garantir que os dados sejam estruturas conforme mostrado, poderíamos usar, cut
mas em vez de dividir em um delimitador, poderíamos apenas exibir usando as posições reais dos caracteres.
Exemplo
Isso cortará o texto do data.txt
arquivo e imprimirá o que estiver nas posições 9 a 13 e 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
estranho revisitado
O Awk também pode extrair texto com base em sua posição, e não por um delimitador. É mais detalhado, mas veja como, apenas 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
awkFIELDWIDTHS
Se estiver usando uma variante do GNU, awk
você pode usar a variável FIELDWIDTHS
para especificar o tamanho estático de cada campo. Isso acaba sendo muito mais limpo que o substr
método, se você tiver acesso a ele. Além disso, você pode unir efetivamente campos que, de outra forma, seriam analisados 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
Responder2
Meu palpite é que não acho que sejam guias. A razão pela qual não acho que sejam guias é porque quando copio o arquivo e tabulo manualmente os campos, parece cut -f 3,4,5,8 filename
funcionar bem. Talvez seja melhor fazer isso cat filename | awk '{print $3, $4, $5, $8}'
se não quiser retabular campos e valores.