ファイル名のリストを引数として受け取り、別の引数ファイルの最初の引数ファイル内の各単語の発生回数を計算して報告するシェルスクリプトを探しています。
ファイルに単語が表示される回数を計算する方法を理解しています。
このトリックを使用しています。
$ tr ' ' '\n' < FILE | grep -c WORD
ファイル数のためにn
詰まっています。
これが私が今まで得たものです:
#!/bin/bash
if [ $# -lt 2 ]
then
echo "Very less arguments bro."
fi
search_file=`tr '\n' ' ' < $1` # Make the first file in to a sequence of words.
for other_file in "$@"
do
if [ $other_file = $1 ]
then
continue
fi
# Modify this file such that each space turns in to a newline
tr ' ' '\n' < $other_file > new_temp_file
for search_word in $search_file
do
word_freq=`grep -c $search_word new_temp_file`
echo "Word=$search_word Frequency=$word_freq"
done
done
答え1
私はそれをします:
#! /bin/sh -
# usage: wordcount <file-with-words-to-search-for> [<file>...]
words=$(tr -s '[[:space:]]' '[\n*]' < "${1?No word list provided}" | grep .)
[ -n "$words" ] || exit
shift
for file do
printf 'File: %s\n' "$file"
tr -s '[[:space:]]' '[\n*]' | grep -Fxe "$words" | sort | uniq -c | sort -rn
done
(これは各ファイルで少なくとも1回以上見つかった単語の数だけを提供します)。
答え2
次のように、コマンドラインで提供されているファイルのリストを繰り返すことができます。
for file in "$@"
do
echo "Considering file ==> $file <=="
done
あなたの単語の一致方法は非常に効率的でなければなりません。以下を使用して単語の発生を検索することもできます。grep -o
echo 'I can cry cryogenic tears when I scry my hands. Can you cry too?' |
grep -o '\bcry\b' # \b marks a word boundary
パイプラインを介して結果を入力して、wc -l
入力ストリームの発生回数を取得します。
有効にすると、$( ... )
あるコマンドの出力を別のコマンドで使用されるテキストに挿入できます。例えば
echo "The date and time right now is $(date)"
最初のファイルを検索せずに単語のリストとして使用するには、追加の作業が必要です。しかし、それらを組み合わせると、次のような結果が得られます。
wordfile="$1"
wordlist=($(cat "$wordfile"))
shift
for file in "$@"
do
for word in "${wordlist[@]}"
do
# echo "$file: $word:" $(grep -o "\b${word}\b" "$file" | wc -l) # My way
echo "$file: $word:" $(tr ' ' '\n' <"$file" | grep -c "$word") # Your way
done
done
Nワードごとに各ファイルをN回検索するので、それほど効率的ではありません。これがgrep -f
役に立ちます。
答え3
fgrep -cw 'word' file1 file2 ... fileN
すると、以下が出力されます。
file1:4
file2:16
1行に1つずつ。すべてのファイルの総数の場合は、次のようにします。
echo "Total: $(( $(fgrep -cw 'word' file1 file2 ... fileN | awk -F: '{ print $NF" + " }') 0 ))"
すると、以下が出力されます。
Total: 20