1

sed と基本的なコマンドを使用して、多くの個別のパッセージがある各パッセージの単語数を数えようとしています。各パッセージは特定の番号で始まり、増加します。例:

0:1.1 これが最初の一節です...

0:1.2 これが二節目…

難しいのは、各パッセージが 1 行ではなく単語で折り返された段落になっていることです。1 行に収まっていれば、各パッセージの単語を数えることができました。どうすればこれを行うことができますか?助けてくれてありがとう

私は各パッセージを数える方法を考え出しました:

grep '[0-9]:[0-9]' ファイル | トイレ -l

4

4 に答える 4

1

このawk解決策はあなたのために働くかもしれません:

awk '/^[0-9]:[0-9]\.[0-9]/{ 
       if (pass_num) printf "%s, word count: %i\n", pass_num, word_count
       pass_num=$1
       word_count=-1
     }
     { word_count+=NF }
     END { printf "%s, word count: %i\n", pass_num, word_count }
    ' file

テスト入力:

# cat file
0:1.1 I am le passage one.
There are many words in me.

0:1.2 I am le passage two.
One two three four five six
Seven

0:1.3 I am "Hello world"

テスト出力:

0:1.1, word count: 11
0:1.2, word count: 12
0:1.3, word count: 4


使い方:

各単語は空のスペースで区切られているため、各単語はの各フィールドで表すことができますawk。つまり、1行の単語数はに等しくなりNFます。単語数は、次のパッセージまですべての行に合計されます。

新しいパッセージ(パッセージ番号の存在によって示される)に遭遇すると、

  • 前のパッセージの数と単語数を出力します。
  • パッセージ番号をこの新しいパッセージ番号に設定します
  • パッセージの単語数をリセットします(-1パッセージ番号をカウントしたくないため)

最後のEND{..}パッセージにはパッセージ番号と単語数を出力するトリガーがないため、ブロックが必要です。

最初のパッセージに遭遇したときif (pass_num)に抑制することです。printfawk

于 2012-11-04T09:13:01.087 に答える
1

これはあなたのために働くかもしれません(GNU sed):

sed -r ':a;$bb;N;/\n[0-9]+:[0-9]+\.[0-9]+/!s/\n/ /g;ta;:b;h;s/\n.*//;s/([0-9]+:[0-9]+\.[0-9]+)(.*)/echo "\1 = $(wc -w <<<"\2")"/ep;g;D' file

各セクションを1行に形成し、セクション内の単語からセクション番号を差し引いた数をカウントします(改行はスペースに置き換えられます)。

于 2012-11-04T09:47:13.073 に答える
0
$ cat file
0:1.1 This is the first passage...
welcome to the SO, you leart a lot of things here.

0:1.2 This is the second passage...
wer qwerqrq            ewqr e
0:1.3 This is the second passage...

sedとGNUgrepの使用:

$ sed -n '/0:1.1/,/[0-9]:[0-9]\.[0-9]/{//!p}' file | grep -Eo '[[:alpha:]]*'   | wc -l
11

0:1.1->カウントしたいパッセージ番号をここに入力します。

于 2012-11-04T06:55:18.223 に答える
0

GNU awk の 1 つの方法を次に示します。

awk -v RS='[0-9]+:[0-9]+\\.[0-9]+' -v FS='[ \t\n]+' 'NF > 0 { print R ": " NF - 2 } { R = RT }'

doubledownでリストされたファイルに対して実行すると、出力は次のようになります。

0:1.1: 11
0:1.2: 12
0:1.3: 4

説明

これは、空白に従って入力をレコードに[0-9]+:[0-9]+\\.[0-9]+分割し、フィールドに分割することで機能します。レコード セパレータは 1 ずれて{R = RT }いるため、各レコードは で開始および終了するため、フィールド カウンタは 2 ずれてFSNF - 2ます。

編集 - 次を含むフィールドのみを数えます[:alnum:]

上記は、たとえば省略記号 (...) も単語としてカウントします。これを避けるには、次のようにします。

awk -v RS='[0-9]+:[0-9]+\\.[0-9]+' -v FS='[ \t\n]+' '
  NF > 0 { 
    wc = NF-2
    for(i=2; i<NF; i++)
      if($i !~ /[[:alnum:]]+/)
        wc--
    print R ": " wc
  } 
  { R = RT }'
于 2012-11-04T10:09:48.537 に答える