Como awk e printf colunas usando formatação e incluindo todas as colunas depois do dia 9

0

Eu tenho o script abaixo para imprimir todas as colunas especificadas do 1º ao 9º usando o printf para o formato, no entanto, gostaria de imprimir qualquer coluna depois da 9ª coluna e não tenho certeza de como fazer isso

pwd='pwd'
#Megabytes
max_size_1='ls -ltr "$pwd" | grep -v "total" | awk '{print $1}' | sort -n | tail -1 | wc -m'
max_size_2='ls -ltr "$pwd" | grep -v "total" | awk '{print $2}' | sort -n | tail -1 | wc -m'
max_size_3='ls -ltr "$pwd" | grep -v "total" | awk '{print $3}' | sort -n | tail -1 | wc -m'
max_size_4='ls -ltr "$pwd" | grep -v "total" | awk '{print $4}' | sort -n | tail -1 | wc -m'
max_size_5='ls -ltr "$pwd" | grep -v "total" | awk '{$5=sprintf("%.0f M", $5/1024^2)} 1' | awk '{print $5}' | sort -n | tail -1 | wc -m'


ls -ltr "$pwd" | grep -v "total" | awk '{$5=sprintf("%.0f M", $5/1024^2)} 1' | eval "awk '{printf \"%$max_size_1-s %$max_size_2-s %$max_size_3-s %$max_size_4-s %$max_size_5-s %-3s %-3s %-3s %-6s\n\", \, \, \, \, \, \, \, \, \}'"

A saída é:

-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:45 
-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:45 
-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:46 
-rwxr-xr-x  1  informix  informix  0  M   Mar 9   10:51 
-rw-r-----  1  informix  informix  0  M   Mar 9   12:36 
-rwxrwxrwx  1  informix  informix  0  M   Mar 9   13:01

O que eu gostaria:

-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:45 ls-ltrg
-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:45 ls-ltrk
-rwxr-xr-x  1  informix  informix  0  M   Mar 1   13:46 ls-ltrb
-rwxr-xr-x  1  informix  informix  0  M   Mar 9   10:51 ls-ltrm
-rw-r-----  1  informix  informix  0  M   Mar 9   12:36 split word
-rwxrwxrwx  1  informix  informix  0  M   Mar 9   13:01 test.sh

Ele deve imprimir todas as colunas depois de nove arquivos pares ou nomes que são divididos depois disso.

    
por Christopher Karsten 09.03.2017 / 12:05

1 resposta

0

Descobri que este é um problema interessante a ser enfrentado, principalmente como uma oportunidade de aprendizado no awk.

A análise de ls é robusta complicado e não recomendado, então não vou passar por cima desses detalhes aqui. Se os nomes de seus arquivos nunca contiverem novas linhas, você poderá usar o seguinte script awk para fazer todo o trabalho que estava fazendo em partes separadas:

  • exibindo a linha "total"
  • obtendo o tamanho de cada campo
  • formatando dinamicamente as colunas

... tudo sem chamar ls, grep, awk, sort, tail e wc várias vezes, e sem precisar usar eval .

Como ls lista o diretório atual ( pwd ) por padrão, eu também removi isso.

Algumas notas aleatórias:

  • meu awk não inicializou i no primeiro uso para zero, então eu o forcei a zero no bloco BEGIN

  • a parte grep -v total acontece com a linha única: /^total / { next; }

  • a solução real para sua pergunta atual está no for loop onde consolidamos as informações do nome do arquivo nas colunas 9 .. NF.

  • a formatação vem em duas partes: o primeiro loop for no bloco END determina a largura que precisamos; o segundo loop for usa o especificador de formato * para fazer o trabalho real - passando a largura desejada à frente do valor real.

Aqui está o script / código resultante:

ls -ltr | awk '
        BEGIN {
                i=0;
        }

        /^total / { next; }
        {
                perms[i]=$1
                links[i]=$2
                owner[i]=$3
                group[i]=$4
                $5=sprintf("%.0f M", $5/1024^2)
                size[i]=$5
                date[i]=$6 " " $7 " " $8
                for(x=9; x <= NF; x++) name[i] = name[i] " " $x
                i++
        }

        END {
                for(j=0;j<i;j++) {
                        if (length(perms[j]) > maxperms) maxperms = length(perms[j])
                        if (length(links[j]) > maxlinks) maxlinks = length(links[j])
                        if (length(owner[j]) > maxowner) maxowner = length(owner[j])
                        if (length(group[j]) > maxgroup) maxgroup = length(group[j])
                        if (length(size[j]) > maxsize) maxsize = length(size[j])
                }
                for(j=0;j<i;j++) {
                        printf "%-*s %-*s %-*s %-*s %-*s %s %s\n",
                                maxperms, perms[j],
                                maxlinks, links[j],
                                maxowner, owner[j],
                                maxgroup, group[j],
                                maxsize, size[j],
                                date[j],
                                name[j]
                }
        }
        '

Um enorme obrigado ao G-Man, que forneceu uma folha de dicas pronta para usar na formatação de colunas dinâmicas do awk .

    
por 10.03.2017 / 19:37

Tags