タブ形式のファイルがあります。すべての行に同じ数のタブがあるかどうかを確認したいと思います。
最初のステップとして、個々の行のタブ数を印刷したいと思います。
私はもう試した grep -o '\t' infile | wc -l
ですが、私のgrep
の実装はgrep: invalid option -- o
。他の方法はありますか?
ありがたいこと:可能であれば、個人的な好みにより、util(grep、catなど)ツール、できればnotawk
またはbashスクリプトを使用してこれを実行することをお勧めします。
sed
などはこれには適していないと思います。簡単な方法は、フィールド区切り文字としてタブを使用してawk
を呼び出すことです。
printf $'hello\tworld\thugo\nfoo\tbar\nbaz\n' | awk -F$'\t' '{print NF-1;}'
これは
2
1
0
1行に常に同じ数のタブがあるかどうかを検出することだけが目標の場合(bashやawkなし):
sed 's/[^\t]//g' file | sort -u | wc -l
1を出力するなら、それは良いことです!
または、sed
をtr
に置き換えます。
tr -cd \\t\\n < file | sort -u | wc -l
または、猫の無駄な使用が好きで、オプションの連結が嫌いな場合:
cat file | tr -c -d \\t\\n | sort -u | wc -l
秘訣は、各行のタブ以外の文字をすべて削除してから、残っている文字を並べ替え/一意にすることです。
正直なところ、最も簡単な方法はawk
を使用することです。
awk -F'\t' '{print NF-1}' foo
NF
はフィールドの数であり、-F'\t'
はawk
にタブのフィールドを分割するように指示します。これにより、タブの数はフィールドの数より1つ少なくなります。そのためawk
print NF-1
。
本当にawk
を使用したくない場合は、次のようにすることができます(注:これは各行の終わりにある末尾のタブをカウントしません):
$ while read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
2
4
0
1
0
先頭と末尾のタブ、およびその他の奇妙な文字(円記号など)を処理するには、代わりに次のようにします。
$ while IFS= read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
while read lines; do ... ; done < foo
:ファイルfoo
の各行を変数$line
に読み込みます。echo "$line" | fold -1
:foldコマンドは1行に1文字を出力しますgrep -c $'\t'
:これはファイルの各行($line
)で実行されますが、$line
は1行に1文字に折りたたまれているため、grep -c
は次のタブの数をカウントします。その行。最初にfold
を実行しない場合、grep -c
は一致する行の数をカウントし、タブ数を取得しませんper行。もちろんPerlを使用することもできますが、それも利用できないと思います。関係なく1つの方法があります:
Perl -lne '@a=/\t/g;print scalar @a' foo
私は遅すぎますが、OPのコマンドラインはほぼ正しかったです。彼はTABの前に$が必要でした( '\ t')
grep -o $'\t' infile | wc -l
彼が求めていたものをexacltyします。