テキスト ファイルの定義済み単語ごとに増分カウントを追加するにはどうすればよいでしょうか?

テキスト ファイルの定義済み単語ごとに増分カウントを追加するにはどうすればよいでしょうか?

テキスト ファイルの定義済み単語ごとに増分カウントを追加するにはどうすればよいでしょうか?

この質問のように: テキスト ファイルの各行に増分カウントを追加するにはどうすればよいですか?

テキスト ファイルに増分カウントを追加したいのですが、各行に増分カウントを追加するのではなく、定義済みの単語に増分カウントを追加したいと思います。

たとえば、テキスト内の「cinema」という単語をカウントしたい場合、「cinema」のすべての出現箇所を「cinemaN」に変更します。ここで、N は増分数であり、N の最大値はテキスト内で「cinema」という単語が何回出現するかによって異なります。

つまり、次のテキストを含む入力テキスト ファイルは次のようになります。

彼は車で映画館まで行き、チケットを購入するために映画館に入ったが、その後、最後に映画館を訪れてから2年以上経っていることに気づいた。

次の内容の出力ファイルを生成します:

彼は車で映画館1まで行き、その後、チケットを購入するために映画館2に入りましたが、その後、最後に映画館3を訪れてから2年以上経っていることに気づきました。

できれば、選択した単語を逆順に番号付けできるようにしたいと思います。

つまり、次の内容の 2 番目の出力ファイルが生成されます。

彼は車で映画館3まで行き、その後、チケットを購入するために映画館2に入りましたが、その後、最後に映画館1を訪れてから2年以上経っていることに気づきました。

答え1

私はperlこれを好みます:

$ cat ip.txt 
He drove his car to the cinema. He then went inside the cinema to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema.

$ # forward counting is easy
$ perl -pe 's/\bcinema\b/$&.++$i/ge' ip.txt 
He drove his car to the cinema1. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema3.
  • \bcinema\b検索する単語。単語の境界を使用して、別の単語の一部として一致しないようにします。たとえば、またはまたはは\bpar\b一致しません。apartparkspar
  • geこのgフラグはグローバル置換用です。e置換セクションで Perl コードを使用できます。
  • $&.++$i一致した単語と、$iそのデフォルト値が0


リバースの場合は、まずカウントを取得する必要があります...

$ c=$(grep -ow 'cinema' ip.txt | wc -l) perl -pe 's/\bcinema\b/$&.$ENV{c}--/ge' ip.txt 
He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema1.
  • cハッシュを介して環境変数にアクセスできるようになります%ENV

または、perlファイル全体を丸呑みするだけで

perl -0777 -pe '$c=()=/\bcinema\b/g; s//$&.$c--/ge' ip.txt 

答え2

複数文字の RS、大文字と小文字を区別しないマッチング、単語境界用の GNU awk を使用:

$ awk -v RS='^$' -v ORS= -v word='cinema' '
    BEGIN { IGNORECASE=1 }
    { cnt=gsub("\\<"word"\\>","&"); while (sub("\\<"word"\\>","&"cnt--)); print }
' file
He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and afterwards discovered that it was more then two years since he last visited the cinema1.

答え3

単語の後の句読点を考慮します。
前方番号付け:

word="cinema"
awk -v word="$word" '
    { 
      for (i = 1; i <= NF; i++) 
        if ($i ~ word "([,.;:)]|$)") { 
          gsub(word, word "" ++count,$i) 
        }
      print 
    }' input-file

逆番号付け:

word="cinema"
count="$(awk -v word="$word" '
    { count += gsub(word, "") }
    END { print count }' input-file)"
awk -v word="$word" -v count="$count" '
    { 
      for (i = 1; i <= NF; i++) 
        if ($i ~ word "([,.;:)]|$)") { 
          gsub(word, word "" count--, $i) 
        }
      print 
    }' input-file

答え4

単語を降順でタグ付けするには、正規表現を反転し、データを反転し、最後に日付をもう一度反転して変換を実行します。

perl -l -0777pe '$_ = reverse reverse =~ s/(?=\bamenic\b)/++$a/gre' input.data

結果

He drove his car to the cinema3. He then went inside the cinema2 to purchase tickets, and
afterwards discovered that it was more then two years since he last visited the cinema1.

単語を昇順でタグ付けするには、単語の後読み検索を実行します。

perl -lpe 's/\bcinema\b\K/++$a/eg' input.data

結果

He drove his car to the cinema1. He then went inside the cinema2 to purchase tickets, and
afterwards discovered that it was more then two years since he last visited the cinema3.

関連情報