2011-12-25 25 views
48

Dato un file con i dati di questo tipo (cioè stores.dat del file)unix - numero di colonne nel file

sid|storeNo|latitude|longitude 
2|1|-28.03720000|153.42921670 
9|2|-33.85090000|151.03274200 

Quale potrebbe essere un comando per l'uscita del numero di nomi di colonna?

cioè Nell'esempio di cui sopra sarebbe 4. (numero di caratteri pipe + 1 nella prima riga)

Stavo pensando qualcosa del tipo:

awk '{ FS = "|" } ; { print NF}' stores.dat 

ma restituisce tutte le linee, invece di solo la prima e la prima riga restituisce 1 invece di 4

risposta

76
awk -F'|' '{print NF; exit}' stores.dat 

Basta chiudere subito dopo la prima riga.

+1

o 'awk -F '|' 'NR == 1 {print NF}' stores.dat' –

+10

@JaypalSingh: questo leggerà l'intero file - non ce n'è bisogno, meglio fermarsi prima. – Mat

+0

Entrambi sembrano restituire la stessa uscita corretta, c'è qualche vantaggio sulle prestazioni di 1 rispetto all'altro (o qualche altro vantaggio)? – toop

9

A meno che non si stiano utilizzando gli spazi, è possibile utilizzare | wc -w sulla prima riga.

wc è "Conteggio parole", che conta semplicemente le parole nel file di input. Se invii solo una riga, ti dirà la quantità di colonne.

+0

Ho provato: head -1 stores.dat | wc -w Ma questo non restituisce quello che sto dopo – toop

+0

Questo perché non stai sostituendo '|' con uno spazio - 'wc' conterà le parole, che devono essere separate da spazio. Usa 'head -1 stores.dat | tr '|' '' | | wc -w' –

+2

Per favore aggiungi il tuo commento alla risposta per completezza. – Xofo

28

Si tratta di una soluzione (per me: io non uso molto spesso awk):

Visualizzare la prima riga del file contenente i dati, sostituire tutti i tubi con a capo e poi contare le righe:

$ head -1 stores.dat | tr '|' '\n' | wc -l 
+6

Per i file con colonne di maaany (si pensi ai dati SNP) questa è la strada da percorrere. La soluzione di Mat ha restituito "awk: limite del programma superato: numero massimo di campi size = 32767". –

1

Se avete python installato si potrebbe provare:

python -c 'import sys;f=open(sys.argv[1]);print len(f.readline().split("|"))' \ 
    stores.dat 
+0

in questo caso particolare, è più breve da leggere dallo standard input 'cat x.txt | python -c "print raw_input(). count ('|') + 1" ' –

+0

più corto sì, ma non più veloce, se ci sono molti file lunghi! Supponevo che volesse una soluzione più veloce nell'occhio dei file di dati puri (significa sicuramente grandi). –

1

Questo è di solito quello che uso per il conteggio del numero di campi:

head -n 1 file.name | awk -F'|' '{print NF; exit}' 
4

Si potrebbe provare

cat FILE | awk '{print NF}'

1

soluzione simile a Perl soluzione awk di Mat:

perl -F'\|' -lane 'print $#F+1; exit' stores.dat 

Ho provato questo su un file con 1000000 colonne.


Se il separatore di campo è spaziatura (uno o più spazi o tabulazioni) invece di un tubo:

perl -lane 'print $#F+1; exit' stores.dat 
0

base alla risposta Cat Kerr. Questo comando sta lavorando su Solaris

awk '{print NF; exit}' stores.dat 
+0

E quindi sei alla risposta accettata meno il separatore di campo appropriato. Ciò restituirebbe "1" per l'input di esempio. –

+0

Questa è essenzialmente la stessa risposta accettata senza separatore di campo, come dice Bejamin restituisce 1, ma dovrebbe funzionare per i file delimitati dallo spazio. – discipulus

0

potete provare:

head -1 stores.dat | grep -o \| | wc -l 
0

selezionare qualsiasi riga nel file (nell'esempio qui sotto, è la 2 ° fila) e contare il numero di colonne, in cui il delimitatore è uno spazio:

sed -n 2p text_file.dat | tr ' ' '\n' | wc -l 
Problemi correlati