Quando si contano le righe con wc, non stampare un errore ogni volta che è una directory


12

Voglio contare il numero totale di righe in tutti i /etcfile ma non i file nelle sottodirectory, quindi ho digitato: wc -l /etc/* | tail -1e l'output è simile a:

xxxx is a directory 
yyyy is a directory
total 1752

La mia domanda è: come posso eliminare (eliminare) questi commenti e c'è un modo migliore per fare questo tipo di conteggio?


1
Penso che usare find non sia wright al 100%, perché in / etc non ci sono solo file regolari f ma anche collegamenti l. quindi questa versione è molto migliore: $ sudo wc -l / etc / * 2> / dev / null | coda -1
Hamza

Risposte:


14

È possibile generare i messaggi di errore su / dev / null

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

Con questo comando stai vedendo solo il numero di righe nei file che sono leggibili dal mondo. Per vedere il numero di righe di tutti i file dovresti elevare il comando con sudo.

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

8

Isola i file ed esegui wc su di essi

Quello che wc -l /etc/*fa è che *si espanderà a tutti gli elementi all'interno della /etc/directory. Quindi l'obiettivo è quindi isolare i file ed eseguirli wc. Esistono diversi modi per farlo.

per loop con test

Il testcomando, o più frequentemente abbreviato come [può essere utilizzato per scoprire se un elemento è un file normale in questo modo:

[ -f "$FILE" ]

Pertanto, ciò che possiamo fare è iterare su tutti gli elementi /etc/ed eseguirli wcse e solo se il comando sopra restituisce true. Così:

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

trova

Possiamo anche usare findcon -maxdepth, -typee -execbandiere

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

  • -maxdepthinforma quanto è profonda la struttura della directory da percorrere; il valore 1 indica solo i file nella directory che vogliamo.
  • -type f gli dice di cercare file regolari, OR (rappresentato da -oflag) per collegamenti sybolic (rappresentati da type l). Tutta quella bontà è racchiusa tra parentesi ()sfuggite in \modo che la shell le interpreti come parte del findcomando, piuttosto che qualcos'altro.
  • -exec COMMAND {} +la struttura qui esegue qualsiasi comando gli diamo, +indicando di prendere tutti i file trovati e riempirli come argomenti della riga di comando al COMANDO.

Per produrre il totale, potremmo inoltrare l'output in questo tailmodo

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

Nota a margine

È più semplice da usare wc -l /etc/* 2>/dev/null | tail -1, come nella risposta di LD James, tuttavia finddovrebbe essere parte dell'abitudine di trattare i file per evitare l'elaborazione di nomi di file difficili. Per maggiori informazioni a riguardo leggi il saggio Come trattare correttamente i nomi dei file


5

find lo fa facilmente:

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

Produzione:

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

MA se vuoi solo il numero come output e nient'altro:

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

EDIT : prevale l' newlineserrore kos detto. Solo usando lo -execrettifica. Inoltre, /etcnon contiene tali file.

Produzione:

8169

Come indicato da kos , il comando sopra può essere ridotto a:

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

EDIT : prevale l' newlineserrore kos detto. Solo usando lo -execrettifica. Inoltre, /etcnon contiene tali file.

Produzione:

8169

4
Qual è lo scopo di -iname '*'? non findcorrisponde a tutto per impostazione predefinita?
steeldriver

@steeldriver - Senza di me non ha funzionato '*'.
Raffaello

2

Usando z-shell ( zsh), la regina delle conchiglie , invece di bash.

sudo wc -l /etc/*(.) | tail -1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.