2

任意の数のテキストファイルを取り込んで、出現回数による単語の分布である出力を提供する実行可能ファイルを作成しようとしています。これはbashスクリプトで実行する必要があり、これまでのところ、次のようになっています。

#!/bin/bash
y=$(cat $* | wc -w)

cat $* | tr ' ' '//' |  tr '[:upper:]' '[:lower:]' | tr -d '[:punct:]' | 
grep -v '[^a-z]'| sort | uniq -c | sort -rn | head -$y

設定しようとするとエラーが発生し、それ以外の方法ですべての単語を印刷するy方法がわかりません。head

それを印刷するより良い方法はありますか?

4

1 に答える 1

1

なぜ走るheadのですか?ファイル内の単語と同じ数の単語があるという保証はありません。実際、(繰り返しの単語があるため) 存在しないことが実質的に保証されています。そして、すべてのデータを表示したい場合は、すべてのデータを表示します。からの出力をフィルタリングしないでくださいsort -nr

最初のtrスラッシュは 1 つだけ必要だと思います。通常、空白と句読点を改行にマップします (隣接する改行を 1 つに絞り込む-sオプションを使用)。tr最初のスラッシュtrは 3 番目の句読点としてカウントされるtrため、何をしているのかは明らかではありません。私は次のようなものを見ると思うと思います:

cat "$@" |
tr -cs '[:alpha:]' '\n' |      # Convert any non-alpha character to newline
tr '[:upper:]' '[:lower:]' |   # Case-convert to lower case
sort | uniq -c | sort -nr

"$@"ではなく$*;の使用に注意してください。指定したファイル名に空白 (改行、タブなど) が含まれていない場合でも違いはありません。その場合、"$@"フォームは正しく、正しく$*ないため、常に を使用することもできます"$@"。それは実際よりもはるかに頻繁に正しい$*です。

私が転がっていたいくつかの C ソース コードでは、スクリプトからの出力は次のようになりました。

 246 n
 217 i
 153 int
 141 list
 124 if
 118 t
 103 char
  99 a
  97 size
  90 buffer
  89 context
  82 d
  81 void
  79 include
  79 h
  78 s
  65 for
  62 j
  55 ptr
  54 r
  54 const
  53 static
  53 sem
  51 pthread
  49 z
  49 oldneedle
  49 err
  47 to
  47 return
  46 mutex
  44 printf
  43 error
  43 c

「h」という単語は、「include」という単語と同じくらい頻繁に現れることに注意してください。それには理由があります!単語tがたくさん出てきますが、それは例えば、size_tフィルタリングで2つの単語として扱われているためです。アンダースコアを保持することは可能です。最初trに使用するものを変更します'[:alpha:]_'(アンダースコアに注意してください)。数字を削除しましたが、必要に応じて保持することもできます。

于 2013-02-06T23:36:32.710 に答える