Comando de corte que não extrai campos adequadamente em colunas alinhadas

3

Eu tenho um arquivo de texto no qual devo cortar 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 do arquivo original. O que esta acontecendo aqui? Por que isso não funciona?

    
por starhacker 02.10.2013 / 07:22

2 respostas

5

Nem todos os espaços entre as colunas parecem ser guias, então cut não poderá fazer o que você deseja. Eu sugeriria usar awk . É mais flexível que cut ao 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 comando column :

$ 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 apenas 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 trabalho OK, mas não manipulam nenhuma das linhas onde há espaços dentro do valor para uma coluna específica. Por exemplo, a linha com "Dept Manager" é cortada para apenas Dept.

Se os dados puderem ser garantidos como estruturas, como 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 arquivo data.txt e imprimirá o que estiver nas posições de 9 a 13 e de 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

O awk também pode ser feito para extrair o texto com base em sua posição e não por um delimitador. É mais detalhado, mas aqui está como, apenas pela perfeição.

$ 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 FIELDWIDTHS

Se você estiver usando uma variante do GNU awk , poderá usar a variável FIELDWIDTHS para especificar o tamanho estático de cada campo. Isso é muito mais limpo que o método substr , se você tiver acesso a ele. Além disso, você pode efetivamente colar juntos campos que 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      
    
por 02.10.2013 / 07:50
1

Meu palpite é que não acho que sejam guias. A razão pela qual eu não acho que eles são guias é porque quando eu copio e cole o arquivo manualmente, então o cut -f 3,4,5,8 filename parece funcionar bem. Talvez seja melhor você fazer cat filename | awk '{print $3, $4, $5, $8}' se não quiser retabular campos e valores.

    
por 02.10.2013 / 07:50