Conta nul elementi delimitati nel file


8

Ho uno script di shell che utilizza find -print0per salvare un elenco di file da elaborare in un file temporaneo. Come parte della registrazione, vorrei visualizzare il numero di file trovati e quindi ho bisogno di un modo per ottenere quel conteggio. Se l' -print0opzione non fosse utilizzata per sicurezza, potrei usare wc -lper ottenere il conteggio.


Risposte:


11

Alcune opzioni:

tr -cd '\0' | wc -c

tr '\n\0' '\0\n' | wc -l      # Generic approach for processing NUL-terminated
                              # records with line-based utilities (that support
                              # NUL characters in their lines like GNU ones).

grep -cz '^'                  # GNU grep

sed -nz '$='                  # recent GNU sed, no output for empty input

awk -vRS='\0' 'END{print NR}' # not all awk implementations

Si noti che per un input che contiene dati dopo l'ultimo carattere NUL (o input non vuoto senza caratteri NUL), gli trapprocci conteranno sempre il numero di caratteri NUL, ma gli approcci awk/ sed/ grepconteranno un record aggiuntivo per quei byte extra .


Li ho misurati su 5 GB di dati casuali ( head -c 5G /dev/urandom > f). Risultati: grep 1.7s (uguale per grep -Fcz '') • tr + wc-c 7.7s • tr + wc-l 7.4s • sed 34.7s • awk 1m11.7s
Socowi

@Socowi, YMMV con l'implementazione e le impostazioni internazionali. Con GNU awk, ti consigliamo di impostare le impostazioni locali su C(o qualsiasi altra che non usi caratteri multibyte),LC_ALL=C awk ... < f
Stéphane Chazelas il

Grazie per il suggerimento. Ho già utilizzato LC_ALL=Csu sortcui non ha fatto accelerare le cose, quindi, per fortuna ho ancora il file da prima: LC_ALL=C awk ...prende 6.7s.
Socowi,

4

Il metodo migliore a cui sono stato in grado di pensare è usare grep -zc '.*'. Funziona, ma sembra sbagliato usare grep con uno schema che corrisponderà a qualsiasi cosa.


1

Con perl:

perl -0ne 'END {print $.}'

o:

perl -nle 'print scalar split "\0"'

o:

perl -nle 'print scalar unpack "(Z*)*", $_'

Il primo conterà un record extra se ci sono dati dopo l'ultimo NUL. Gli altri 2 non funzionano se l'input contiene caratteri di nuova riga.
Stéphane Chazelas,

@ StéphaneChazelas: Oh, mio ​​cattivo. Potresti dare qualche miglioramento?
cuonglm

Vorrei solo conservare il primo e menzionare il fatto che conta un record non delimitato (contrariamente a wc -l) come una nota (come si potrebbe desiderare).
Stéphane Chazelas,
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.