いくつかのテキスト処理ユーティリティで各行の特定の文字数を計算する方法を知りたいです。
たとえば、"
次のテキストの各行を計算します。
"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
tr
Aidを使用してください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