1

Alright, I have two folders. For simplicity's sake, I'll call them players and items. The items folder has a file for each item, and the people folder has a file for each person with references to which animals that person owns. This is what I have so far:

ls -1 ~/items | cut -d. -f1 | grep -R -f - ~/player

The grep syntax I got from here. I'm trying to get it to say:

electric: 8
laser: 7
loltrail: 2

Instead, I add the -c flag to grep and I get:

Bob.txt: 0
Cathy.txt: 0
John.txt: 0
Patrick.txt: 1

How do I get counts of the items in total, not the items for each person?

This is for figuring out how many items are being used in the Pointshop addon for Garry's Mod.

1
  • 1
    So you just want to add all the numbers obtained from grep output?
    – nitishch
    Apr 26, 2015 at 5:19

2 Answers 2

1

Here’s a way to get the results you want with GNU awk:

awk '
    BEGINFILE {
        if (FILENAME ~ "^animals/"  ||  FILENAME ~ "/animals/") {
                this_name = substr(FILENAME, index(FILENAME,"animals/")+length("animals/"))
                i = index(this_name, ".")
                if (i > 0) this_name = substr(this_name, 1, i-1)
                critter[++num] = this_name
                critter_count[num] = 0
                nextfile
        }
    }
    {
        for (i = 1; i <= num; i++) {
                if ($0 ~ critter[i]) critter_count[i]++
        }
    }
    END {
        for (i = 1; i <= num; i++) print critter[i] ": " critter_count[i]
    }
'  animals/*  people/*
  • Upon starting a new file (BEGINFILE), check whether its name begins with animals/ or contains /animals/.  This lets you say animals/*, ./animals/*, or ~/animals/*.  If it does,

    • Extract the substring to the right of animals/.
    • Then look for a .; if found, extract the substring to the left of it.
    • Add this string (the base filename, with directory and extension removed) to the critter[] array, and initialize the corresponding critter_count to 0.

    ☛  Note that BEGINFILE and nextfile are not available in POSIX awk.

  • Otherwise (if we’re looking at a people file), loop through the animal names (critters) and count the lines that match them.
  • Upon reaching the END of all input, report the animal names that were extracted from the names of the animals files, and the counts of how often each appeared in a people file.

This won’t search the people directory recursively; I didn’t see any statement in the question that that was desired.

2
  • Would it take me 8 years to reply to and finally accept an answer for the Garry's Mod server I was running? No, no no no of course not. Though I may be packing up to move and have seen all these files go over the wire to my NAS and remembered this lol. Sep 2 at 18:47
  • This was originally to get a count of items used in the Pointshop addon for a Garry's Mod server, which by your name I assume you're a fan of Half-Life 2 or Doki Doki Literature Club? Well, thank you very much for this write-up and I'm glad I can finally check this off my to-do list from 2015. Sep 2 at 18:48
1

I think if you give the patterns as input to grep using stdin, it will concatenate results for all patterns. So AFAIK the only way to overcome this problem is to call a new instance of grep for each pattern.

This script would work in this case

for animalName in $(ls -1 ~/animals | cut -d. -f1);
    do
        echo "$animalName: $(grep -R -h -c $animalName ~/people | paste -sd+ | bc)";
done

This is on the lines of what you have tried with some minor changes. First, -h option in grep suppresses printing of file names. Second, with just grep, output for a pattern would be like

1
0
3
2

We want to add all these numbers. paste command joins these lines with a + and then passes the formed string to bc to calculate the result.

NOTE: If your animal names contain newlines or any special characters (in some strange land), it is not advisable to parse the output of ls.

1
  • This worked too! Thanks for the suggestion. I ended up going with the awk answer because that gives more leeway in what can be added to the script in the future. For instance, each item is in a category and I could count which categories are most popular. Sep 2 at 18:58

You must log in to answer this question.

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