risposta-alla-domanda-sullo-sviluppo-web-bd.com

Contare le lunghezze delle righe nel file utilizzando gli strumenti della riga di comando

Problema

Se ho un file lungo con molte righe di lunghezza variabile, come posso contare le occorrenze di ciascuna lunghezza di riga?

Esempio:

file.txt

this
is
a
sample
file
with
several
lines
of
varying
length

In esecuzione count_line_lengths file.txt darebbe:

Length Occurences
1      1
2      2
4      3
5      1
6      2
7      2

Idee?

60
Peter Hamilton

count.awk:

{
  print length($0);
}

...

$ awk -f count.awk input.txt | sort | uniq -c
      1 1
      2 2
      3 4
      1 5
      2 6
      2 7
87

Awk puro

awk '{++a[length()]} END{for (i in a) print i, a[i]}' file.txt

4 3
5 1
6 2
7 2
1 1
2 2
24
iruvar

Utilizzo di bash array:

#!/bin/bash

while read line; do
    ((histogram[${#line}]++))
done < file.txt

echo "Length Occurrence"
for length in "${!histogram[@]}"; do
    printf "%-6s %s\n" "${length}" "${histogram[$length]}"
done

Esempio di esecuzione:

$ ./t.sh
Length Occurrence
1      1
2      2
4      3
5      1
6      2
7      2
10
$ Perl -lne '$c{length($_)}++ }{ print qq($_ $c{$_}) for (keys %c);' file.txt

Output

6 2
1 1
4 3
7 2
2 2
5 1
7
jfs

È possibile ottenere ciò utilizzando solo le utility di base unix:

$ printf "% s% s\n" $ (per la riga in $ (cat file.txt); esegui printf $ line | wc -c; fatto | ordina -n | uniq -c | sed -E "s/([ 0-9] +) [^ 0-9] + ([0-9] +)/\ 2\1 /")
 1 1 
 2 2 
 4 3 
 5 1 
 6 2 
 7 2 

Come funziona?

  1. Ecco il file sorgente:
    $ cat file.txt 
     questo 
     è 
     un 
     campione 
     file 
     con 
     diversi 
     linee 
     su 
     variabile 
     lunghezza 
    
  2. Sostituisci ogni riga del file sorgente con la sua lunghezza:
    per riga in $ (cat file.txt); fare printf $ line | wc -c; fatto
     4 
     2 
     1 
     6 
     4 
     4 
     7 
     5 
     2 
     7 
     6 
    
  3. Ordina e conta il numero di occorrenze di lunghezza:
    per la riga in $ (cat file.txt); fare printf $ line | wc -c; fatto | ordina -n | uniq -c
     1 1 
     2 2 
     3 4 
     1 5 
     2 6 
     2 7 
    
  4. Scambia e formatta i numeri:
    printf "% s% s\n" $ (per la riga in $ (cat file.txt); fare printf $ line | wc -c; fatto | ordina -n | uniq -c | sed -E "s/([0-9] +) [^ 0-9] + ([0-9] +)/\ 2\1 /") 
     1 1 
     2 2 
     4 3 
     5 1 
     6 2 
     7 2 
    
1
Maksym Ganenko