Ao contar linhas com wc, não imprima um erro sempre que houver um diretório

12

Eu quero contar o número total de linhas em todos os arquivos /etc , mas não os arquivos nos subdiretórios, então eu digitei: wc -l /etc/* | tail -1 e a saída é como:

xxxx is a directory 
yyyy is a directory
total 1752

A minha pergunta é: como posso me livrar desses comentários, e há uma maneira melhor de fazer esse tipo de contagem?

    
por Hamza 02.01.2016 / 13:31

4 respostas

14

Você pode enviar as mensagens de erro para / dev / null

$ wc -l /etc/* 2>/dev/null | tail -1

Com este comando você está vendo apenas o número de linhas nos arquivos que são legíveis pelo mundo. Para ver o número de linhas de todos os arquivos, você teria que elevar o comando com sudo .

$ sudo wc -l /etc/* 2>/dev/null | tail -1
    
por L. D. James 02.01.2016 / 13:39
8

Isole arquivos e execute wc neles

O que wc -l /etc/* faz é que * será expandido para todos os itens dentro do diretório /etc/ . Assim, o objetivo é isolar arquivos e executar wc neles. Existem várias maneiras de fazer isso.

para loop com teste

O comando test , ou mais freqüentemente abreviado como [ , pode ser usado para descobrir se um item é um arquivo regular como este:

[ -f "$FILE" ]

Assim, o que podemos fazer é iterar todos os itens em /etc/ e executar wc neles se, e somente se, o comando acima retornar verdadeiro. Assim:

for i in /etc/*; do [ -f "$i" ] && wc -l "$i" ; done             

encontrar

Também podemos usar find com -maxdepth , -type e -exec flags

find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} +

  • -maxdepth informa como a estrutura do diretório deve ser usada; valor de 1 significa apenas os arquivos no diretório que desejamos.
  • -type f diz para procurar arquivos regulares, OR (representado por -o flag) para links simbólicos (representados por type l ). Toda essa bondade é colocada entre parênteses () escape com \ , de modo que o shell interpreta-os como parte do comando find , em vez de outra coisa.
  • -exec COMMAND {} + structure aqui executa qualquer comando que dermos, + indicando para pegar todos os arquivos encontrados e preenchê-los como argumentos da linha de comando para o COMMAND.

Para produzir o total, poderíamos canalizar a saída para tail da mesma forma

$ find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} + | tail -n 1           
[sudo] password for xieerqi: 
 11196  total

Anotação lateral

É mais fácil usar apenas wc -l /etc/* 2>/dev/null | tail -1 , como em Resposta de L. D. James, no entanto find deve ser uma parte de um hábito para lidar com arquivos para evitar o processamento de nomes de arquivos difíceis. Para mais informações, leia o ensaio Como lidar corretamente com nomes de arquivos

    
por Sergiy Kolodyazhnyy 02.01.2016 / 13:55
5

find faz isso facilmente:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*')

Saída:

...
828 /etc/mime.types
25 /etc/ts.conf
66 /etc/inputrc
 0 /etc/subgid-
8169 total

MAS se você quiser apenas o número como saída e nada mais:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | grep total | awk '{print }'

EDITAR : newlines error kos disse que prevalece. Somente usando -exec a retifica. Além disso, /etc não contém esses arquivos.

Saída:

8169

Como apontado por kos , o comando acima pode ser reduzido para:

sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | awk 'END {print }'

EDITAR : newlines error kos disse que prevalece. Somente usando -exec a retifica. Além disso, /etc não contém esses arquivos.

Saída:

8169
    
por Raphael 02.01.2016 / 13:45
2

Usando z-shell ( zsh ), a rainha do as shells , em vez de bash.

sudo wc -l /etc/*(.) | tail -1
    
por A.B. 02.01.2016 / 14:05

Tags