web-dev-qa-db-ja.com

utilsを使用してテキストファイルの1行あたりのタブ数をカウントします

タブ形式のファイルがあります。すべての行に同じ数のタブがあるかどうかを確認したいと思います。

最初のステップとして、個々の行のタブ数を印刷したいと思います。

私はもう試した grep -o '\t' infile | wc -lですが、私のgrepの実装はgrep: invalid option -- o。他の方法はありますか?


ありがたいこと:可能であれば、個人的な好みにより、util(grep、catなど)ツール、できればnotawkまたはbashスクリプトを使用してこれを実行することをお勧めします。

3
n611x007

sedなどはこれには適していないと思います。簡単な方法は、フィールド区切り文字としてタブを使用してawkを呼び出すことです。

printf $'hello\tworld\thugo\nfoo\tbar\nbaz\n' | awk -F$'\t' '{print NF-1;}'

これは

2
1
0
6
tkrennwa

1行に常に同じ数のタブがあるかどうかを検出することだけが目標の場合(bashやawkなし):

sed 's/[^\t]//g' file | sort -u | wc -l

1を出力するなら、それは良いことです!

または、sedtrに置き換えます。

tr -cd \\t\\n < file | sort -u | wc -l

または、猫の無駄な使用が好きで、オプションの連結が嫌いな場合:

cat file | tr -c -d \\t\\n | sort -u | wc -l

秘訣は、各行のタブ以外の文字をすべて削除してから、残っている文字を並べ替え/一意にすることです。

6
gniourf_gniourf

正直なところ、最も簡単な方法は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 
1
terdon

私は遅すぎますが、OPのコマンドラインはほぼ正しかったです。彼はTABの前に$が必要でした( '\ t')

grep -o $'\t' infile | wc -l

彼が求めていたものをexacltyします。

0
tpettinato