テキストファイル()でsumという単語を含む行数を数える必要がありますthe
。an
poem.txt
同時に両方ではありません。
使ってみました。
grep -c the poem.txt | grep -c an poem.txt
the
しかし、合計合計数がan
9行の場合、6という誤った答えが出ます。
単語自体ではなく単語を含む行数を計算したいです。実際の単語だけが計算されるのでandではthe
ありませんが。there
an
Pan
サンプルファイル:poem.txt
Where is the misty shark?
Where is she?
The small reef roughly fights the mast.
Where is the small gull?
Where is he?
The gull grows like a clear pirate.
Clouds fall like old mainlands.
She will Rise calmly like a dead pirate.
Eat an orange.
Warm, sunny sharks quietly pull a cold, old breeze.
All ships command rough, rainy sails.
Elvis Aaron Presley also known simply as the Elvis
He is also referred to as the King
The best-selling solo music artist of all time
He was the most commercially successful artist in many genres
He has many awards including a Grammy lifetime achievement
Elvis in the 1970s has numerous jumpsuits including an eagle one.
追加の説明:この時点でorを含む行数は何ですか?ただし、すべてのandを含む行は計算しないでthe
ください。an
the
an
the car is red - this counted
an apple is in the corner - not counted
hello i am big - not counted
where is an apple - counted
したがって、ここで出力は2でなければなりません。
編集:大文字と小文字の区別は心配しません。
最終編集:すべての助けに感謝します。この問題を正常に解決しました。答えの1つを使用していくつか変更しました。cat poem.txt | grep -Evi -e '\<an .* the\>' -e '\<the .* an\>' | grep -Eci -e '\<(an|the)\>
追加情報を得るために2番目のgrepをaに変更した方法です。すべての助けにもう一度ありがとう! :)-c
-n
答え1
perl -nE 'END {say $c+0} ++$c if /\bthe\b/i xor /\ban\b/i' file
gawk 'END {print c+0} /\<the\>/ != /\<an\>/ {++c}' IGNORECASE=1 file
各式の一致結果を比較すると、所望の結果が得られる。
たとえば、一致結果は\<the\>
0または1です。他の一致の結果が同じ場合、両方の正規表現が見つかったり見つからず、その行は計算されません。異なる場合、一致するものの1つが見つかりましたが、他のものは見つからなかったことを意味するため、カウンタが増加します。
gawkには次のxor()
機能が組み込まれています。
gawk 'END {print c+0} xor(/\<the\>/,/\<an\>/) {++c}' IGNORECASE=1 file
答え2
grepを使用してください:
cat poem.txt \
| grep -Evi -e '\<an\>.*\<the\>' -e '\<the\>.*\<an\>' \
| grep -Eci -e '\<(an|the)\>'
これが重要です一致する線。合計を計算する代替構文を見つけることができます。マッチ以下に。
分解:
まず、grepコマンドは、「an」と「the」を含むすべての行をフィルタリングします。 2番目のgrepコマンドは、「an」または「the」を含む行数を数えます。
c
2番目のgrepから削除すると、-Eci
すべての一致が強調表示されます。
詳細:
この
-E
オプションはgrepの拡張式構文(ERE)を有効にします。この
-i
オプションは、grepが大文字と小文字を区別せずに一致するように指示します。この
-v
オプションはgrepに結果を逆にするように指示します。いいえインクルードモード)この
-c
オプションは、grep に行自体ではなく一致する行数を出力するように指示します。モデル:
\<
単語の始まりと一致します(ありがとう@glenn-jackman)\>
単語の終わりの一致(ありがとうございます。@glenn-jackman)
-->これにより、単語が一致しないことを確認できます。含む「the」または「an」(例:「pan」)
grep -Evi -e '\<an\>.*\<the\>'
したがって、すべての行に一致いいえ「a...」が含まれています。同様に
grep -Evi -e '\<the\>.*\<an\>'
、すべての行を一致させます。いいえ「...an」を含みます。grep -Evi -e '\<an\>.*\<the\>' -e '\<the.*an\>'
3.と4.の組み合わせです。grep -Eci -e '\<(an|the)\>'
「an」または「the」(スペースまたは行の先頭/末尾で囲まれている)を含むすべての行に一致し、一致する行数を印刷します。
編集1:@glenn-jackmanが提案したように、andの代わり\<
に\>
and( |^)
を使用してください。( |$)
編集2:一致する行数の代わりに一致数を計算するには、次の式を使用します。
cat poem.txt \
| grep -Evi -e '\<an\>.*\<the\>' -e '\<the\>.*\<an\>' \
| grep -Eio -e '\<(an|the)\>' \
| wc -l
これは、各一致を別々の行に印刷してから(他の項目なし)、行数を数える-o
grepオプションを使用します。wc -l
答え3
次のGNUawk
プログラムはこの問題を解決する必要があります。
awk '(/(^|\W)[Tt]he(\W|$)/ && !/(^|\W)[Aa]n(\W|$)/) || (/(^|\W)[Aa]n(\W|$)/ && !/(^|\W)[Tt]he(\W|$)/) {c++} END{print c}' poem.txt
c
次の場合、カウンタがインクリメントされます。
- 行は一致しますが
(^|\W)[Tt]he(\W|$)
(最初の文字はthe
大文字と小文字が区別されませんが、前に非単語コンポーネント()または行の\W
先頭() 、後に単語以外のコンポーネント()または行末()が続きます)は一致しません(分離最初 - 文字を区別せずに書く) - または -^
\W
$
(^|\W)[Aa]n(\W|$)
an
- 線は一致します
(^|\W)[Aa]n(\W|$)
が一致しません。(^|\W)[Tt]he(\W|$)
最後に印刷された値ですc
。
\<
「単語の開始」と「単語の終わり」として、およびを使用して\>
少し短くすることができます。
awk '(/\<[Tt]he\>/ && !/\<[Aa]n\>/) || (/\<[Aa]n\>/ && !/\<[Tt]he\>/) {c++} END{print c}' poem.txt
短いのは次のとおりです。
awk '/\<[Tt]he\>/ != /\<[Aa]n\>/ {c++} END{print c}' poem.txt
an
不等式は、合計の1つが線に表示されるか、両方が表示されない場合にのみ真ですthe
。
and / 構成は正規表現構文を拡張するGNU拡張であるawk
ため、このアプローチにはGNUが必要です(しかし、次のように理解することもできます)。\W
\<
\>
\<
\>
BSD正規表現)。
ファイルを入力引数として呼び出すことはstdinで読み取るものを置き換えるため、試したソリューションに示したパイプライン構成は機能しません。grep
したがって、パイプラインの最初の部分は目立たずに消え、出力は完全に最後の部分によって引き起こされます(発生an
、つまり別の言葉で含まれている場合でも同様です)。
答え4
GNU grepとPCREの長さがゼロのアサーションを使用してこれを実行できます。
grep -iP '(?=.*\bthe\b)(?!.*\ban\b)|(?=.*\ban\b)(?!.*\bthe\b)' poem.txt
Where is the misty shark?
...
Eat an orange.
...
grep -ciP '(?=.*\bthe\b)(?!.*\ban\b)|(?=.*\ban\b)(?!.*\bthe\b)' poem.txt
9
Perl(元の場所)でも同じ機能を使用でき、GNU grepが存在しないシステムにもPerlが存在する可能性があります。