Como alinho corretamente o arquivo de texto de várias colunas?

2

Este é o meu arquivo:

TLRUIDA CBdms    Status            DP  6/1/1         DC  6/1/5         0 Y
TLRUIDA CBdms    Status            DP  6/2/1         DC  6/2/5         0 Y
TLRUIDA CBdms    Status            DP  6/3/1         DC  6/3/5         0 Y
TLRUIDA CBdms    Status            DP  6/4/1         DC  6/4/5         0 Y
TLRUIDA CBdms    Status            DP  6/5/1         DC  6/5/5         0 Y
TLRUIDA CBdms    Status            DP  6/6/1         DC  6/6/5         0 Y
TLRUIDA CBdms    Status            DP  6/7/1         DC  6/7/5         0 Y
TLRUIDA CBdms    Status            DP  6/8/1         DC  6/8/5         0 Y
TLRUIDA CBdms    Status            DP  6/9/1         DC  6/9/5         0 Y
TLRUIDA CBdms    Status            DP  6/10/1         DC  6/10/5         0 Y
TLRUIDA CBdms    Status            DP  6/11/1         DC  6/11/5         0 Y
TLRUIDA CBdms    Status            DP  6/12/1         DC  6/12/5         0 Y    

Eu tenho problema de alinhamento da linha após o dígito 10 ser iniciado. E eu quero o formato abaixo mencionado,

TLRUIDA CBdms    Status            DP  6/1/1         DC  6/1/5         0 Y
TLRUIDA CBdms    Status            DP  6/2/1         DC  6/2/5         0 Y
TLRUIDA CBdms    Status            DP  6/3/1         DC  6/3/5         0 Y
TLRUIDA CBdms    Status            DP  6/4/1         DC  6/4/5         0 Y
TLRUIDA CBdms    Status            DP  6/5/1         DC  6/5/5         0 Y
TLRUIDA CBdms    Status            DP  6/6/1         DC  6/6/5         0 Y
TLRUIDA CBdms    Status            DP  6/7/1         DC  6/7/5         0 Y
TLRUIDA CBdms    Status            DP  6/8/1         DC  6/8/5         0 Y
TLRUIDA CBdms    Status            DP  6/9/1         DC  6/9/5         0 Y
TLRUIDA CBdms    Status            DP  6/10/1        DC  6/10/5        0 Y
TLRUIDA CBdms    Status            DP  6/11/1        DC  6/11/5        0 Y
TLRUIDA CBdms    Status            DP  6/12/1        DC  6/12/5        0 Y
    
por pmaipmui 21.01.2016 / 09:44

5 respostas

2

Este comando sed corrige a saída dada:

sed 's=\(D[CP] *./../.\) ==g'

Remove um espaço após o ./../. após DC e DP. Se os outros números também podem ficar mais longos, o sed provavelmente não é a ferramenta certa para o trabalho.

    
por 21.01.2016 / 10:25
9

A ferramenta certa para este trabalho é column . Você pode especificar o separador de coluna com -o (no OS X é -s ), por exemplo:

column -t -o '   ' file

TLRUIDA   CBdms   Status   DP   6/1/1    DC   6/1/5    0   Y
TLRUIDA   CBdms   Status   DP   6/2/1    DC   6/2/5    0   Y
TLRUIDA   CBdms   Status   DP   6/3/1    DC   6/3/5    0   Y
TLRUIDA   CBdms   Status   DP   6/4/1    DC   6/4/5    0   Y
TLRUIDA   CBdms   Status   DP   6/5/1    DC   6/5/5    0   Y
TLRUIDA   CBdms   Status   DP   6/6/1    DC   6/6/5    0   Y
TLRUIDA   CBdms   Status   DP   6/7/1    DC   6/7/5    0   Y
TLRUIDA   CBdms   Status   DP   6/8/1    DC   6/8/5    0   Y
TLRUIDA   CBdms   Status   DP   6/9/1    DC   6/9/5    0   Y
TLRUIDA   CBdms   Status   DP   6/10/1   DC   6/10/5   0   Y
TLRUIDA   CBdms   Status   DP   6/11/1   DC   6/11/5   0   Y
TLRUIDA   CBdms   Status   DP   6/12/1   DC   6/12/5   0   Y
    
por 21.01.2016 / 10:21
3

Nesse caso específico, será suficiente apenas alterar todas as ocorrências de dois ou mais espaços para uma guia:

sed 's/  */\t/g' file

Para uma solução mais geral, você pode garantir que cada coluna seja impressa com a largura correta usando printf . Você pode fazer isso diretamente no shell:

$ while read line; do 
    printf '%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n' $line; 
done < file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

Ou, com mais segurança para entradas arbitrárias:

$ while read a b c d e f g h i; do 
    printf '%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n' "$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h" "$i"; 
done < file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

Você pode fazer isso de maneira mais rápida e sucinta usando algo como perl :

$ perl -lane 'printf "%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n",@F' file
TLRUIDA CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

O benefício de usar printf é que você pode especificar uma largura de coluna mínima para cada coluna. Isso significa que, se uma de suas colunas puder ter um valor muito mais longo, ela ainda funcionará. Por exemplo, se o primeiro campo de uma de suas linhas puder ser averylongfieldindeed , você poderá definir a largura mínima da primeira coluna como 21 e ter saída alinhada:

$ perl -lane 'printf "%-21s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n",@F' file
averylongfieldindeed CBdms Status DP 6/1/1   DC 6/1/5  0 Y 
TLRUIDA              CBdms Status DP 6/2/1   DC 6/2/5  0 Y 
TLRUIDA              CBdms Status DP 6/3/1   DC 6/3/5  0 Y 
TLRUIDA              CBdms Status DP 6/4/1   DC 6/4/5  0 Y 
TLRUIDA              CBdms Status DP 6/5/1   DC 6/5/5  0 Y 
TLRUIDA              CBdms Status DP 6/6/1   DC 6/6/5  0 Y 
TLRUIDA              CBdms Status DP 6/7/1   DC 6/7/5  0 Y 
TLRUIDA              CBdms Status DP 6/8/1   DC 6/8/5  0 Y 
TLRUIDA              CBdms Status DP 6/9/1   DC 6/9/5  0 Y 
TLRUIDA              CBdms Status DP 6/10/1  DC 6/10/5 0 Y 
TLRUIDA              CBdms Status DP 6/11/1  DC 6/11/5 0 Y 
TLRUIDA              CBdms Status DP 6/12/1  DC 6/12/5 0 Y 

Por contraste, o uso de guias não funcionaria:

$ sed  -e "s/\s\+/\t/g" file
averylongfieldindeed    CBdms   Status  DP  6/1/1   DC  6/1/5   0   Y
TLRUIDA CBdms   Status  DP  6/2/1   DC  6/2/5   0   Y
TLRUIDA CBdms   Status  DP  6/3/1   DC  6/3/5   0   Y
TLRUIDA CBdms   Status  DP  6/4/1   DC  6/4/5   0   Y
TLRUIDA CBdms   Status  DP  6/5/1   DC  6/5/5   0   Y
TLRUIDA CBdms   Status  DP  6/6/1   DC  6/6/5   0   Y
TLRUIDA CBdms   Status  DP  6/7/1   DC  6/7/5   0   Y
TLRUIDA CBdms   Status  DP  6/8/1   DC  6/8/5   0   Y
TLRUIDA CBdms   Status  DP  6/9/1   DC  6/9/5   0   Y
TLRUIDA CBdms   Status  DP  6/10/1  DC  6/10/5  0   Y
TLRUIDA CBdms   Status  DP  6/11/1  DC  6/11/5  0   Y
TLRUIDA CBdms   Status  DP  6/12/1  DC  6/12/5  0   Y   
    
por 21.01.2016 / 11:20
0

temos um comando muito simples para isso:

tr -s ' ' <input-file >output-file
A opção

-s remove a ocorrência de <space> (ou qualquer caractere seguindo-a na linha de comando)

    
por 21.01.2016 / 10:30
0

Se você quiser boas colunas na saída do terminal, você não deve usar espaços, mas caracteres chamados "TAB". Um sedeliner que substitui todos os seus espaços por TABs é o seguinte

sed -i -e "s/\s\+/\t/g" your_input_file
    
por 21.01.2016 / 10:10