Cuando cuente líneas con wc, no imprima un error siempre que sea un directorio

12

Quiero contar el número total de líneas en todos los /etcarchivos pero no los archivos en los subdirectorios, así que escribí: wc -l /etc/* | tail -1y la salida es como:

xxxx is a directory 
yyyy is a directory
total 1752

Mi pregunta es, ¿cómo puedo eliminar (eliminar) estos comentarios, y ¿hay una mejor manera de hacer este tipo de conteo?

Hamza
fuente
1
Creo que usar find no es 100% correcto, porque en / etc no solo hay archivos regulares f sino también enlaces l. así que esta versión es mucho mejor: $ sudo wc -l / etc / * 2> / dev / null | cola -1
Hamza

Respuestas:

14

Puede enviar los mensajes de error a / dev / null

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

Con este comando solo está viendo la cantidad de líneas en los archivos que son legibles en todo el mundo. Para ver el número de líneas de todos los archivos con los que tendría que elevar el comando sudo.

$ sudo wc -l /etc/* 2>/dev/null | tail -1
LD James
fuente
8

Aislar archivos y ejecutar wc en ellos

Lo que wc -l /etc/*hace es que *se expandirá a todos los elementos dentro del /etc/directorio. Por lo tanto, el objetivo es aislar los archivos y realizarlos wc. Hay varias formas de hacerlo.

para bucle con prueba

El testcomando, o se abrevia con más frecuencia como [se puede usar para encontrar si un elemento es un archivo normal de esta manera:

[ -f "$FILE" ]

Por lo tanto, lo que podemos hacer es iterar sobre todos los elementos /etc/y ejecutarlos wcsi y solo si el comando anterior devuelve verdadero. Al igual que:

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

encontrar

También podemos utilizar findcon -maxdepth, -typey -execbanderas

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

  • -maxdepthinforma encontrar qué tan profundo en la estructura del directorio para ir; el valor de 1 significa solo los archivos en el directorio que queremos.
  • -type f le dice que busque archivos regulares, O (representado por -ouna marca) para enlaces simbólicos (representados por type l). Todos los que la bondad está encerrado entre paréntesis ()escapado con \por lo que interpreta concha como parte de de findcomandos, en lugar de otra cosa.
  • -exec COMMAND {} +estructura aquí ejecuta cualquier comando que le demos, +lo que indica que debe tomar todos los archivos encontrados y rellenarlos como argumentos de línea de comando al COMANDO.

Para producir el total, podríamos canalizar la salida para que me tailguste

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

Nota al margen

Es más fácil de usar wc -l /etc/* 2>/dev/null | tail -1, como en la respuesta de LD James, sin embargo, finddebería ser parte de un hábito para tratar con archivos para evitar el procesamiento de nombres de archivo difíciles. Para obtener más información al respecto, lea el ensayo Cómo tratar correctamente los nombres de archivo

Sergiy Kolodyazhnyy
fuente
5

find hace eso fácilmente:

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

Salida:

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

PERO si solo quieres el número como salida y nada más:

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

EDITAR : newlineserror kos dijo que prevalece. Solo el uso lo -execrectifica. Además, /etcno contiene dichos archivos.

Salida:

8169

Como señaló kos , el comando anterior se puede reducir a:

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

EDITAR : newlineserror kos dijo que prevalece. Solo el uso lo -execrectifica. Además, /etcno contiene dichos archivos.

Salida:

8169
Rafael
fuente
44
¿Para qué sirve -iname '*'? no findcoincide con todo por defecto?
Steeldriver
@steeldriver: sin mí no funcionó '*'.
Raphael
2

Usando z-shell ( zsh), la reina de las conchas , en lugar de bash.

sudo wc -l /etc/*(.) | tail -1
AB
fuente