Batch file: Count instances of a word

July 14, 2009 at 01:28:53
Specs: Windows NT
Hi

I have a file which is simply a list of names (one per line) sorted in alphabetical order. Each name appears in the list X number of times. I need to count the number of times each name appears. I have been trying to do this with a for loop but am not getting very far.

Grateful for any help.


See More: Batch file: Count instances of a word

Report •


#1
July 14, 2009 at 03:53:24
@echo off & setLocal EnableDELAYedExpansion

for /f "tokens=* delims=" %%a in (myfile) do (
find /c "%%a" < myfile & echo %%a
)


=====================================
If at first you don't succeed, you're about average.

M2


Report •

#2
July 14, 2009 at 18:58:51
Thanks for that. It works but how can I get the results looking something like this in a separate txt file (sorry, should have been more specific in my orignal post)

chris: 29
mike: 317
tom: 175
...


Report •

#3
July 15, 2009 at 01:02:52
you can use vbscript
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\test\file.txt"
Set objFile = objFS.OpenTextFile(strFile)
Set d = CreateObject("Scripting.Dictionary")
Do Until objFile.AtEndOfLine
	strLine = objFile.ReadLine
	c=0
	If Not d.Exists(strLine) Then
		d.Add strLine, 1
	Else
		c = d.Item(strLine)+1
		d.Remove(strLine)
		d.Add strLine, c
	End If
Loop
x=d.Items
y=d.Keys
For Each strkey In y
	WScript.Echo  strkey , d.Item(strkey)
Next

usage:

c:\test> cscript /nologo myscript.vbs > newfile.txt

GNU win32 packages | Gawk


Report •

Related Solutions

#4
July 15, 2009 at 01:09:00
@mech

@echo off & setLocal EnableDELAYedExpansion

for /f "tokens=* delims=" %%a in (myfile) do (
find /c "%%a" < myfile & echo %%a
)

a minor performance issue with this algorithm: let's analyse it for a file with 1000 names.
first the for loop will be looping 1000 times. then, the find command will be called 1000 times. Also, say there are 50 janes, why would you want to find the number of jane again when the first time round, the number of janes is already found.?

GNU win32 packages | Gawk


Report •

#5
July 15, 2009 at 01:20:34
Thanks ghostdog but I'm afraid vbscript is not an option as I am working on servers with very restricted software so this has to be a batch process.

Report •

#6
July 15, 2009 at 02:12:08
Hi ghostdog,

You're quite right that there's plenty of lost motion.

If the files are huge, a third prty tool may be called for. But if he can't use vbs I don't guess that's gonna happen.


=====================================
If at first you don't succeed, you're about average.

M2


Report •

#7
July 15, 2009 at 03:41:32
i don't believe windows servers nowadays do not have vbscript. its installed by default.
.

GNU win32 packages | Gawk


Report •

#8
July 15, 2009 at 03:50:13
Sounds like a classic case of a user with very restrictive rights.


=====================================
If at first you don't succeed, you're about average.

M2


Report •

#9
July 15, 2009 at 04:41:40
Very restrictive and not much fun to work on. Anyway, I will play around with that for loop and see if I can't get it to do what I want. Thanks for the help both.

Report •

#10
July 15, 2009 at 04:51:42
But if you can't use VBScript (cscript.exe) then perhaps you
can't use the FIND command (find.exe) either, which is used by
the batch file.

Report •

#11
July 15, 2009 at 05:33:45
if its for serious work, you should be allowed to use whatever tools you need, even natively.

GNU win32 packages | Gawk


Report •

#12
July 16, 2009 at 06:53:40
Here's a single-pass, "100% Pure Batch"(TM) solution:
@echo off
setlocal EnableDelayedExpansion
set last=
for /f "tokens=*" %%a in (myfile) do (
   if "%%a" == "!last!" (
      set /a count+=1
   ) else (
      if defined last echo !last!: !count!
      set last=%%a
      set /a count=1
   )
)
if defined last echo !last!: !count!


Report •

#13
July 16, 2009 at 08:01:02
doesn't work for me, my output

C:\test>more test.bat
@echo off
setlocal EnableDelayedExpansion
set last=
for /f "tokens=*" %%a in (file.txt) do (
   if "%%a" == "!last!" (
      set /a count+=1
   ) else (
      if defined last echo !last!: !count!
      set last=%%a
      set /a count=1
   )
)
if defined last echo !last!: !count!

C:\test>more file.txt
mike
peter
mike
jane
john
jane
mike

C:\test>test.bat
mike: 1
peter: 1
mike: 1
jane: 1
john: 1
jane: 1
mike: 1

it should show mike:3, jane:2 and so on

GNU win32 packages | Gawk


Report •

#14
July 16, 2009 at 08:06:28
The stated requirement was that it should work with already-sorted files, and that's exactly what it does.

Report •

#15
July 17, 2009 at 04:40:39
Hi klint,

good one


=====================================
If at first you don't succeed, you're about average.

M2


Report •


Ask Question