Listar arquivos com contagem de linha e data

5

Eu quero poder listar arquivos mostrando o número de linhas que cada arquivo possui e a data. Eu posso felizmente obter a contagem de linha usando wc -l * . Não é um problema. Eu posso pegar a data usando ls -l .

Existe uma maneira de combinar os dois comandos para me dar uma única saída em colunas?

    
por John Reid 30.10.2014 / 13:27

5 respostas

7

Aqui está algo com find + wc + date .

find . -maxdepth 1 -exec sh -c '[ -f "$0" ] && \
  printf "%6s\t\t%s\t%s\n" "$(wc -l<"$0")" "$(date -r "$0")" "$0"' {} \;

Em vez de date -r , também é possível usar, por exemplo, stat -c%y .

A saída é assim:

   394      Thu Oct 16 22:38:14 UTC 2014    ./.zshrc
     7      Thu Oct 30 11:19:01 UTC 2014    ./tmp.txt
     2      Thu Oct 30 06:02:00 UTC 2014    ./tmp2.txt
    40      Thu Oct 30 04:16:30 UTC 2014    ./pp.txt

Usando isso como ponto de partida, pode-se criar uma função que aceita diretório e padrão como parâmetros:

myls () { find "$1" -maxdepth 1 -name "$2" -exec sh -c '[ -f "$0" ] && \
  printf "%6s \t\t%s\t%s\n" "$(wc -l<"$0")" "$(date -r "$0")" "$0"' {} \;; }

Depois disso, myls /tmp '*.png' listará apenas imagens de /tmp (observe as aspas simples ao redor do padrão para evitar que o shell expanda um operador glob * ).

    
por 30.10.2014 / 13:54
2

As soluções baseadas em find parecem as mais elegantes, mas apenas por diversão, aqui estão algumas outras maneiras de atacar isso.

Este usa sed & head para limpar a saída de wc e, em seguida, usa join para combiná-la com a saída de stat , usando o nome do arquivo como o campo de associação.

pat="A*";join -1 2 -2 1 -t ' ' <(wc -l $pat|head -n-1|sed 's/^[ ]*//') <(stat -c '%n %y' $pat) | awk '{printf "%-20s %6s %s %s %s\n",$1,$2,$3,$4,$5}'

E um mais simples que usa paste , com awk novamente arrumando as colunas e também verificando se os nomes dos arquivos correspondem.

pat="A*";paste -d ' ' <(wc -l $pat) <(stat -c '%n %y' $pat) | awk '$2==$3{printf "%6s %s %s %s\n", $1, $4, $5, $2}'

No entanto, se os nomes não coincidirem (as listas de arquivos são alteradas enquanto o comando está em execução), os erros ficam invisíveis. Mas esta versão relata os erros:

pat="A*";paste -d ' ' <(wc -l $pat) <(stat -c '%n %y' $pat) | awk '$2==$3{printf "%6s %s %s %s\n", $1, $4, $5, $2;next};{print "Error:" $0}'

É claro que essa será uma mensagem de erro para a linha final, mas isso é fácil de corrigir. Ou ignore. :)

    
por 30.10.2014 / 14:37
0

Eu usei awk como mostrado abaixo:

wc -l * | head --lines=-1 | while read num file
do
  echo -n $num" "
  ls -l $file | awk '{
     for (i=6; i <= NF; i++)
       printf $i " "
  }'
  echo
done
  • head é usado para remover a última linha (linha total de wc output).
  • num contém o número da linha de file .
  • awk é usado para imprimir a saída de tempo de ls -l output.
por 30.10.2014 / 14:05
0

Eu usei xargs com find :

find . -type f | xargs -i  sh -c 'echo -n 'date -r {}'; \
     echo -n "    "; echo -n 'wc -l {}'; echo '

Saída:

Thu Oct 30 19:16:38 IST 2014    0 ./b
Thu Oct 30 19:16:38 IST 2014    0 ./a
Thu Oct 30 19:16:38 IST 2014    0 ./c
Thu Oct 30 19:16:56 IST 2014    10 ./testfile

Pouca formatação com printf em vez de echo como feito por @jimmij:

find . -type f | xargs -i sh -c 'printf "%s\t%s\t\n" \
     "$(date -r {} +%x\ %H:%M:%S)" "$(wc -l {})" '
    
por 30.10.2014 / 14:38
-1

E sobre:

ls -lrth yourfile|awk '{print $6 $7 " " $8 system("wc -l " $9) }' | tr '\n' ' '
    
por 30.10.2014 / 13:40