各行の特定の文字数を計算する方法は?

各行の特定の文字数を計算する方法は?

いくつかのテキスト処理ユーティリティで各行の特定の文字数を計算する方法を知りたいです。

たとえば、"次のテキストの各行を計算します。

"hello!" 
Thank you!

最初の行には2つ、2番目の行には0があります。

(別の例は、各行を計算することです。

答え1

sed以下を使用してこれを実行できますawk

$ sed 's/[^"]//g' dat | awk '{ print length }'
2
0

datサンプルテキストはどこにありますか? sedは(各行ごとに)"文字以外のすべてを削除し、各行awkのサイズを印刷します(つまり、現在の行を表す位置lengthと同じ)。length($0)$0

他のキャラクターの場合、sed式を変更するだけです。例えば(:

's/[^(]//g'

修正する: sed仕事のための少し過剰 -tr適切なもの以上です。同等のソリューションtrは次のとおりです。

$ tr -d -c '"\n' < dat | awk '{ print length; }'

文字セット(補足コードを表す)にないtrすべての文字を削除することを意味します。-c"\n

答え2

私はawkだけを使うでしょう

awk -F\" '{print NF-1}' <fileName>

ここでは、-Fフラグを使用してフィールド区切り文字を文字に設定してから、フィールド"NF-1を印刷するだけです。対象文字の発生回数は、区切りフィールド数より1少ない。

興味深い文字をシェルで解釈するには、その文字をエスケープする必要があります。それ以外の場合は、コマンドラインでその文字を解釈しようとします。したがって、どちらの場合も、フィールド区切り文字をエスケープする必要があります(使用")。)\

答え3

trAidを使用してくださいwc

function countchar()
{
    while IFS= read -r i; do printf "%s" "$i" | tr -dc "$1" | wc -m; done
}

使用法:

$ countchar '"' <file.txt  #returns one count per line of file.txt
1
3
0

$ countchar ')'           #will count parenthesis from stdin
$ countchar '0123456789'  #will count numbers from stdin

答え4

awk一致する数が多すぎる(私の場合)、失敗した回答が使用されます。答えが必要な場合ロッキーアスタリ、次のエラーが報告されます。

awk -F" '{print NF-1}' foo.txt 
awk: program limit exceeded: maximum number of fields size=32767
    FILENAME="foo.txt" FNR=1 NR=1

答えが必要な場合エンゾチップ(そしてそれに対応する従業員)、分割エラーが発生します。

awk '{ gsub("[^\"]", ""); print length }' foo.txt
Segmentation fault

ソリューションsedを通過マックスシュレプチガーうまくいきますが、非常に遅いです(下記の時間)。

いくつかの解決策はまだここに提案されていません。まず、以下を使用してくださいgrep

grep -o \" foo.txt | wc -w

そして使用perl

perl -ne '$x+=s/\"//g; END {print "$x\n"}' foo.txt

以下はいくつかの解決策のタイミングです(最も遅いものから最も速いものの順に並べ替え)。ここでは数言だけ申し上げます。 'foo.txt'は、1行と84922個の一致を含む長い文字列で構成されるファイルです。

## sed solution by [maxschlepzig]
$ time sed 's/[^"]//g' foo.txt | awk '{ print length }'
84922
real    0m1.207s
user    0m1.192s
sys     0m0.008s

## using grep
$ time grep -o \" foo.txt | wc -w
84922
real    0m0.109s
user    0m0.100s
sys     0m0.012s

## using perl
$ time perl -ne '$x+=s/\"//g; END {print "$x\n"}' foo.txt
84922
real    0m0.034s
user    0m0.028s
sys     0m0.004s

## the winner: updated tr solution by [maxschlepzig]
$ time tr -d -c '\"\n' < foo.txt |  awk '{ print length }'
84922
real    0m0.016s
user    0m0.012s
sys     0m0.004s

関連情報