1

I am working on writing a bash script which takes multiple files as input and display the top ‘n’ most frequently occurring words in descending order for each of file.

I figured out how to count the frequency of words for 1 file but I am unable to figure out how I will deal when I have multiple files and process them parallelly.

 sed -e 's/[^[:alpha:]]/ /g' testfile.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

this works fine for 1 file but I want to write a bash script which I can run like following:

$countWord test1.txt test2.txt test3.txt (countword here is my bash script that counts freq)

I want it to take those files as input and for each file show me something like:

   ===(1 51 33 test1.txt)====    # where 1: number of lines, 51: number of words, 33: number of characters
38 them
29 these
17 to
12 who

 

Any help in right direction is greatly appreciated. :)

2 Answers 2

1

Make a loop on the file

for F in "$@"
do echo "=== $F ==="
    sed -e 's/[^[:alpha:]]/ /g' "$F" | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
done

have fun !

2
  • 2
    Use double-quoted "$@" instead of $*. It will correctly handle file names with spaces. And then double-quote your variables whenever you use them, again for the same reason. Generally, I'd also avoid using capital letters for variables in case they clash with reserved variables.
    – roaima
    Feb 9, 2022 at 8:04
  • Thank you very much. Feb 9, 2022 at 16:33
1

Using this input:

$ head file1 file2
==> file1 <==
I am new here. I am working on writing a bash script which takes multiple files
as input and display the top ‘n’ most frequently occurring words in
descending order for each of file.

==> file2 <==
I figured out how to count the frequency of words but I am unable to figure out
how I will deal when I have multiple files.

and GNU awk in a shell script:

$ cat tst.sh
#!/usr/bin/env bash

awk '
    BEGIN { maxWords = 5 }
    {
        gsub(/[^[:alpha:]]/," ")
        for (i=1; i<=NF; i++) {
            words[$i]++
            split($i,tmp)
            for (j in tmp) {
                chars[tmp[j]]++
            }
        }
    }
    ENDFILE {
        print "  ===(" FNR+0, length(words)+0, length(chars)+0, FILENAME ")==="
        PROCINFO["sorted_in"] = "@val_num_desc"
        numWords = 0
        for (word in words) {
            print words[word], word
            if ( ++numWords == maxWords ) {
                break
            }
        }
        delete cnt
        delete chars
    }
' "${@:--}"

we get:

$ ./tst.sh file1 file2
  ===(3 32 32 file1)===
2 am
2 I
1 writing
1 working
1 words
  ===(2 45 20 file2)===
6 I
3 am
2 words
2 to
2 the

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .