Text analysis

Hey Guys,

Does anyone know how to count the separate amount of words in a text file?
e.g
the 5
and 20
Furthermore does anyone know how to convert whole numbers in decimals?

Thanks

tr '[ \r\t]' ' ' < file | wc -l

For the second I don't understand the question. what do you get in and what do you want out?

Hey,
Thanks for the post
I want to convert the number you'd get for each word counted e.g. the: 46, into a decimal number so in this case '46'.

Thanks,

Try this

awk '{for (i=1;i<=NF;i++){a[$i]++}} END{for (j in a){print j,a[j]}}' <inputFile>

Explain what you're trying to achieve and post your input file and the desired output.

xargs -n1 <infile | wc -l

---------- Post updated at 07:47 PM ---------- Previous update was at 07:32 PM ----------

For fun ... with pure sed :

# cat tst
1 2 3 4
A B C
XX YY ZZ AA WWW
# ./ts2 <tst
12

For those who don't already know this example ...

@Bartus (here is a geek example, i hope you'll especially enjoy it !!! :D)

HERE IS THE CHALLENGE :

Understand how this sed code works (this should make your brain work quite a bit ) :wink: !!!
(i mean the whole algoritm, not only what each line does)

# cat ts2
#!/bin/sed -nf
s/[[:blank:]][[:blank:]]*/ /g
s/^/ /
s/ [^ ][^ ]*/a /g
s/ //g
H
x
s/\n//
/aaaaaaaaaa/! bx;   s/aaaaaaaaaa/b/g
/bbbbbbbbbb/! bx;   s/bbbbbbbbbb/c/g
/cccccccccc/! bx;   s/cccccccccc/d/g
/dddddddddd/! bx;   s/dddddddddd/e/g
/eeeeeeeeee/! bx;   s/eeeeeeeeee/f/g
/ffffffffff/! bx;   s/ffffffffff/g/g
/gggggggggg/! bx;   s/gggggggggg/h/g
s/hhhhhhhhhh//g
:x
$! { h; b; }
:y
/a/! s/[b-h]*/&0/
s/aaaaaaaaa/9/
s/aaaaaaaa/8/
s/aaaaaaa/7/
s/aaaaaa/6/
s/aaaaa/5/
s/aaaa/4/
s/aaa/3/
s/aa/2/
s/a/1/
y/bcdefgh/abcdefg/
/[a-h]/ by
p

Hey Guys

I recently posted yesterday about trying to count the amount of separate words that exists in a text file e.g. walle.txt.
i want the output to give to give me a list of words with a number next indicating how many times its came up in the file e.g:
cat 20
the 11
if 40

I'm completely new to Unix, I'm currently using the bash terminal from a Macbook Pro. I am running this on some example file scripts, is what i'm trying to do possible? if so please help.

Thanks

How the posted solutions NOT fulfilling the above request?
As always, please provide a sample input file a desired output (using code tags).

xargs -n1 <yourfile.txt | sort | uniq -c

---------- Post updated at 05:59 PM ---------- Previous update was at 05:54 PM ----------

the simple quote may annoy xargs so we can change it into a white space at first with a sed statement :

sed "s/'/ /g" yourfile.txt | xargs -n1 | sort | uniq -c

Hey,

Thanks for the reply, i just tried both statements and 'illegal argument count' keeps coming up :\

Please upload your text file so we can try with a real example and we will let you know if some other step are needed

Try to go through a tempfile then.

give a try to this:

sed "s/'/ /g" yourfile.txt >file.tmp
xargs -n1 <file.tmp >file.tmp.2
sort file.tmp.2 >file.tmp.sorted
uniq -c file.tmp.sorted >wordcount.txt
rm file.tmp*
cat wordcount.txt

Okay Thanks,

I've attached it below

OMG ... i doesn't really look like a txt file, but more like a binary file !
(... forget my previous post)
give a try to this:

strings yourfile.txt | sed "s/'/ /g" | xargs -n1 | sort | uniq -c

I gave it a go and it still says 'illegal argument count' :confused:

In fact your document is a Microsoft Word document

Open it in word, and save it as a txt ...

# file walle.txt
walle.txt:      Microsoft Word Document

You must change case to lower, I like tr, then separate all the words, say using sed, then count them, sort to uniq -c.

tr '[:upper:]' '[:lower]' <yourfile.txt | sed '
  s/[^a-z]\{1,99\}/\
/g
 ' | sort | uniq -c >wordcount.txt

For big files with mostly repeating words, you may need a less disk-space intensive, intelligent solution. I wrote this in C, instructions included, replace "sort | uniq -c" with "aggsx -l". (Some features are aimed at the Interbase/Firebird RDBMS.) (You could write a more elegant and faster on using a hash map container in C++ or JAVA, and do the case and separation in code, too.)

$ cat mysrc/aggsx.c
 
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
static  long double     sum = 0.0 ;
static  long double     nval ;
static  unsigned long   lct = 0 ;
static  unsigned long   nct = 0 ;
static  unsigned long   ll2 ;
static  unsigned long   nvc = 0 ;
static  unsigned long   dct = 0 ;
static  unsigned long   act = 0 ;
static  unsigned long   ll ;
static  unsigned long   mpc = 0 ;
static  unsigned long   *vct = NULL ;   /* value counts */
static  unsigned long   *lp ;
static  char            **vl = NULL ;   /* value list */
static  char            **cpp ;
static  char            *cp ;
static  char            *cp2 ;
static  char            *cp3 ;
static  char            *me = "" ;
static  char            *mp = "" ;
static  char            *pfx = NULL ;
static  int             i ;
static  int             d = 0 ; /* -d option */
static  int             u = 0 ; /* -u option */
static  int             l = 0 ; /* -l option */
static  int             b = 0 ; /* -b option */
static  int             num = 1 ;
static  int             lfm ;   /* line feed missing */
static  char            buf[66000] ;
static  void            fmv( char *val )
{
        unsigned long   cv ;
        unsigned long   cl = 0 ;
        unsigned long   ch ;
        int             r ;
        char            **cf ;
        char            **ct ;
        char            **ce ;
        unsigned long   *lf ;
        unsigned long   *lt ;
        if ( dct )
                for ( cl = 0, ch = dct - 1 ; cl <= ch ; )
                {
                        cv = ( ch + cl ) >> 1 ;
                        r = strcmp( val, vl[cv] );
                        if ( r > 0 )
                        {
                                cl = cv + 1 ;
                        }
                        else if ( r < 0 )
                        {
                                if ( cv )
                                        ch = cv - 1 ;
                                else
                                        break ;
                        }
                        else
                        {
                                lt = vct + cv ;
                                *lt += 1 ;
                                if ( d
                                  && *lt == 2 ) /* report dups */
                                {
                                        if ( 0 > printf( "%s\n", val )
                                          || fflush( stdout ) )
                                        {
                                                if ( ferror( stdout ) )
                                                {
                                                        perror( "stdout" );
                                                        exit( 1 );
                                                }
                                                exit( 0 );
                                        }
                                }
                                return ;
                        }
                }
        if ( u ) /* report unique */
        {
                if ( 0 > printf( "%s\n", val )
                  || fflush( stdout ) )
                {
                        if ( ferror( stdout ) )
                        {
                                perror( "stdout" );
                                exit( 1 );
                        }
                        exit( 0 );
                }
        }
        cv = dct ;
        if ( ++dct > act )
        {
                act += 1024 ;
                if ( !( vl = realloc( vl, act * sizeof( char* ) ) ) )
                {
                        perror( "realloc()" );
                        exit( 1 );
                }
                if ( !( vct = realloc( vct, act * sizeof( long ) ) ) )
                {
                        perror( "realloc()" );
                        exit( 1 );
                }
        }
        for ( ce = vl + cl,
                cf = ( ( ct = vl + cv ) - 1 ),
                lf = ( ( lt = vct + cv ) - 1 ) ;
              ct > ce ;
              cf--, ct--, lf--, lt-- )
        {
                *ct = *cf ;
                *lt = *lf ;
        }
        *lt = 1 ;
        if ( !( *ct = malloc( strlen( val ) + 1 ) ) )
        {
                perror( "malloc()" );
                exit( 1 );
        }
        strcpy( *ct, val );
        return ;
}
int main( int argc, char **argv ){
        setvbuf( stdin, NULL, _IOFBF, PIPE_MAX );
        setvbuf( stdout, NULL, _IOFBF, PIPE_MAX );
        for ( i = 1 ; i < argc ; i++ )
        {
                if ( !strcmp( argv[1], "-b" ) )
                {
                        b = 1 ;
                        continue ;
                }
                if ( !strcmp( argv[1], "-l" ) )
                {
                        l = 1 ;
                        continue ;
                }
                if ( !strcmp( argv[1], "-p" )
                  && ++i < argc )
                {
                        pfx = argv;
                        continue ;
                }
                if ( !strcmp( argv[1], "-u" ) )
                {
                        u = 1 ;
                        continue ;
                }
                if ( !strcmp( argv[1], "-d" ) )
                {
                        d = 1 ;
                        continue ;
                }
                if ( !strcmp( argv[1], "-h" ) )
                {
                        fputs( 
"CtD|CtN|Min|CtMin|Max|CtMax|Avg|Med|MPop|CtMPop|Ct\n",
                                stdout );
                        continue ;
                }
                fputs(
"Usage:\n"
"\n"
"aggsx [ -b ] [ -l ] [ -p <prefix> ] [ -u ] [ -d ] [ -h ]\n"
"\n"
"Computes the count distinct, count null, min, count of min, max,\n"
"count of max, average (mean) of not null values if numeric,\n"
"median of not null values, largest of the most popular values,\n"
"count of that most popular value.\n"
"\n"
"If -l is present, first prints out all values in order and their counts,\n"
"null last, but no aggregates.\n"
"If -b is present, prints out like -l and then prints aggregates.\n"
"If -p is present, the aggregate is prefixed with '<prefix>|'.\n"
"If -u is present, just immediately prints out unique values.\n"
"If -d is present, just immediately prints out duplicated values.\n"
"If -h is present, prefixes values line with header line:\n"
"CtD|CtN|Min|CtMin|Max|CtMax|Avg|Med|MPop|CtMPop\n"
"\n"                    , stderr );
                exit( 1 );
        }
        while( fgets( buf, sizeof( buf ), stdin ) )
        {
                lct++ ;
                for ( cp = buf, cp2 = cp3 = NULL, lfm = 1 ; *cp ; cp++ )
                {
                        switch( *cp )
                        {
                        case '\n':
                                lfm = 0 ;
                                /* intentional fall through */
                        case '\r':
                                /* intentional fall through */
                        case ' ':
                                /* intentional fall through */
                        case '\t':
                                continue ;
                                /* intentional fall through */
                        default:
                                if ( !cp2 )
                                {
                                        cp2 = cp ;
                                }
                                cp3 = cp ;
                        }
                }
                if ( lfm )
                {
                        fprintf( stderr, "\nFatal: Data line %lu too long!\n",
                                                lct );
                        exit( 1 );
                }
                if ( cp3 )
                {
                        *(++cp3) = NULL ;
                        cp = cp2 ;
                }
                if ( strcmp( cp, "<null>" ) )
                {
                        fmv( cp );
                }
                else
                {
                        nct++ ;
                }
        }
        if ( ferror( stdin ) )
        {
                perror( "stdin" );
                exit( 1 );
        }
        if ( u
          || d )
                exit( 0 );
        if ( l || b )
        {
                for ( ll = 0, cpp = vl, lp = vct ;
                        ll < dct ;
                        ll++, lp++, cpp++ )
                {
                        if ( 0 > printf( "%lu\t%s\n", *lp, *cpp ) )
                        {
                                if ( ferror( stdout ) )
                                {
                                        perror( "stdout" );
                                        exit( 1 );
                                }
                                exit( 0 );
                        }
                }
                if ( nct
                  && 0 > printf( "%lu\t%s\n", nct, "<null>" ) )
                {
                        if ( ferror( stdout ) )
                        {
                                perror( "stdout" );
                                exit( 1 );
                        }
                        exit( 0 );
                }
                if ( !b )
                {
                        exit( 0 );
                }
        }
        for ( ll = 0L, cpp = vl, lp = vct, ll2 = ( ( lct - nct ) >> 1 ) + nct ;
              ll < dct ; ll++, lp++, cpp++ )
        {
                cp = *cpp ;
                if ( *lp >= mpc )
                {
                        mpc = *lp ;
                        mp = cp ;
                }
                if ( *cp
                  && num )
                {
                        errno = 0 ;
                        nval = strtod( cp, &cp2 );
                        if ( errno              /* underflow or overflow */
                          || ( cp2 == cp )      /* didn't like the characters */
                          || *cp2 )             /* didn't like some */
                        {
                                num = 0 ;
                        }
                        else
                        {
                                sum += ( nval * *lp ) ;
                                nvc += *lp ;
                        }
                }
                if ( ll2 <= lct  )
                {
                        me = cp ;
                        ll2 += *lp ;
                }
        }
        if ( num
          && nvc )
        {
                sum /= nvc ;
                sprintf( buf, "%-30.20LG", sum );
                for ( cp = buf + strlen( buf ) - 1 ;
                      cp >= buf && *cp == ' ' ;
                      cp-- )
                {
                        *cp = NULL ;
                }
        }
        else
        {
                strcpy( buf, "N/A" );
        }
        if ( ( ( pfx
              && 0 > printf( "%s|", pfx ) )
            || 0 > printf( "%lu|%lu|%s|%lu|%s|%lu|%s|%s|%s|%lu|%lu\n",
                                dct, nct,
                                ( dct ? vl[0] : "" ),
                                ( dct ? vct[0] : 0 ),
                                ( dct ? vl[dct - 1] : "" ),
                                ( dct ? vct[dct - 1] : 0 ),
                                buf, me, mp, mpc, lct ) )
          && ferror( stdout ) )
        {
                perror( "stdout" );
                exit( 1 );
        }
        exit( 0 );
}

I am not sure whether anybody mentioned to you but when you use a variable under 'awk' that is originally a string (because you piped it as a string from somewhere or you used it as a string in the first place), then you just have to add a number to it and 'awk' converts the result into a number. Usually you add 0 (zero) to it.

Here is an example that should work for you:

wc -w inputfile | cut -c 1-9 | awk '{print $1 + a} a=0'

In my case, the inputfile had 10 words and awk returned 10 at the end. You can easily see this when you add a number to the result (like "1" in the case below)"

wc -w inputfile | cut -c 1-9 | awk 'END {c=$1+a; print c} a=1'
      10
11

I think he wanted word frequency, not total word count. He could have used a tool like awk, perl and put 1 or value+1 to a variable for every word in lower case, then dump the variables.

Hey guys,

Does anybody know how to parse a large text file to remove punctuation completely, so it only displays text?

Thanks

look into 'man tr'.