web-dev-qa-db-ja.com

unix-ファイル内の列数

このようなデータを含むファイルがある場合(つまり、stores.datファイル)

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

列名の数を出力するコマンドは何でしょうか?

つまり、上記の例では4です(パイプ文字の数+ 1行目の1)

私は次のようなものを考えていました:

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

ただし、最初の行だけでなくすべての行を返し、最初の行については4ではなく1を返します

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

最初の行の直後に終了します。

98
Mat

これは回避策です(私にとって:awkはあまり使用しません):

データを含むファイルの最初の行を表示し、すべてのパイプを改行で置き換えてから、行をカウントします。

$ head -1 stores.dat | tr '|' '\n' | wc -l
34
miku

そこにスペースを使用していない限り、最初の行で| wc -wを使用できるはずです。

wcは「Word Count」で、入力ファイル内の単語を単純にカウントします。 1行のみを送信する場合、列の量がわかります。

11

試すことができます

猫FILE | awk '{print NF}'

4
Cat Kerr

pythonがインストールされている場合は、次を試すことができます。

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

Matのawkソリューションに似たPerlソリューション:

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

これを1000000列のファイルでテストしました。


フィールド区切り文字がパイプではなく空白(1つ以上のスペースまたはタブ)の場合:

Perl -lane 'print $#F+1; exit' stores.dat
1
Chris Koknat

これは通常、フィールドの数を数えるために使用するものです。

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

適切な純粋 bash way

Bashでは、次のことが簡単にできます。

IFS=\| read -ra headline <stores.dat
echo ${#headline[@]}
4

forkなしではるかに高速で、$headlineとして再利用可能です。あなたは、サンプルのために:

printf " - %s\n" "${headline[@]}"
 - sid
 - storeNo
 - latitude
 - longitude

Notaこの構文は、列名のスペースやその他の文字を正しく駆動します。

代替:各行の最大列の強力なバイナリチェック

行に余分な列が含まれている場合はどうなりますか?

このコマンドはseparatorsをカウントして、より大きな行を検索します:

tr -dc $'\n|' <stores.dat |wc -L
3

最大3つのセパレーターがあり、次に4つのフィールドがあります。

0
F. Hauri

Cat Kerr応答に基づきます。このコマンドはsolarisで機能しています

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

ファイル内の任意の行を選択し(以下の例では2行目)、区切り文字がスペースである列の数をカウントします。

sed -n 2p text_file.dat | tr ' ' '\n' | wc -l
0
sAguinaga

あなたが試すことができます:

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