0

I need some help with the following;

a) Write a single command that creates a file, where the file contains the number of parameters for both TCP and UDP. It should not include parameters for other protocols (such as IP or XFRM) in the count.

These parameters are set in individual files in /proc/sys/net/ipv4/, where the protocol (TCP or UDP) is determined by the first few letters in the filename. one line).

The single command may use pipes and re-direction, but must not simply combine commands (e.g. using ;). An example of the first few lines of the contents is:
63 tcp
3 udp

This is what i have so far:

ls -l /proc/sys/net/ipv4 | grep -n "tcp\|udp"| cut -d " " -f 10| cut -c 1-3 
0

4 Answers 4

1

In this instance I would not try to use pipes or redirection to count the files, and instead let the shell do it for me:

$ set -- /proc/sys/net/ipv4/tcp*
$ printf '%d tcp\n' "$#"
73 tcp
$ set -- /proc/sys/net/ipv4/udp*
$ printf '%d udp\n' "$#"
5 udp

or, written to an output file:

{ set -- /proc/sys/net/ipv4/tcp*; printf '%d tcp\n' "$#"
  set -- /proc/sys/net/ipv4/udp*; printf '%d udp\n' "$#"; } >outputfile

You could artificially turn that into a single compound command, but nobody would write code like this:

$ set -- /proc/sys/net/ipv4/tcp* && printf '%d tcp\n' "$#" && set -- /proc/sys/net/ipv4/udp* && printf '%d udp\n' "$#"
73 tcp
5 udp

In both these sets of commands, the files are counted by expanding a filename globbing pattern, setting the positional parameters to the expanded list of pathnames, and then simply outputting the number of elements in the lists.

You would get the wrong counts if either pattern did not match anything (1 instead of 0). You could correct for that by setting the nullglob shell option in bash.

This happens to also cover theoretical corner cases with filenames containing newlines and whatever other strange characters.


An awk command that does the same thing as above (i.e. counts the number of times filenames starting with tcp and udp occurs):

awk '
    BEGIN {
        for (i=1;i<ARGC;++i) { sub(".*/","",ARGV[i]); sub("_.*","",ARGV[i]); c[ARGV[i]]++ }
        for (i in c) print i, c[i]
    }' /proc/sys/net/ipv4/{tcp,udp}*
0

You don't need the -l option, since you are not interested in file details like permissions, ownership and size. Only the filename is needed.

The grep command is not working. grep won't help anyway, since the question asks you to separately count the tcp and udp files.

To count files, you can use ls|wc -l. To count files whose names start with "tcp": ls tcp*|wc -l. Do the same for "udp" and combine the two numbers in an echo:

echo -e "$(ls /proc/sys/net/ipv4/tcp*|wc -l) tcp\n$(ls /proc/sys/net/ipv4/udp*|wc -l) udp" > out

The -e is required to process the newline.

This would not work if filenames included newlines, but we can safely assume that this is not the case in /proc/sys/net/ipv4.

Upon rereading the question, I am not sure if my answer is correct. It merely counts files, not parameters. I need to make an assumption now: A parameter is a word in such a file. Most files contain a single word, but some contain more. To count words, use wc -w. Instead of ls, use cat to access file content:

echo -e "$(cat /proc/sys/net/ipv4/tcp*|wc -w) tcp\n$(cat /proc/sys/net/ipv4/udp*|wc -w) udp" > out
2
  • Thank you i figured out a way but it was slightlty different same results however, thank you for your help :)
    – Voiletta
    Apr 4, 2021 at 7:23
  • Include what you figured out. The more solutions, the better. Apr 4, 2021 at 7:25
-1

All you are missing from your example is to pipe it to uniq -c like so:

ls -l /proc/sys/net/ipv4 | grep -n "tcp\|udp"| cut -d " " -f 10| cut -c 1-3 | uniq -c

This is what I got when I ran it on my system:

$ ls -l /proc/sys/net/ipv4 | grep -n "tcp\|udp"| cut -d " " -f 10| cut -c 1-3 | uniq -c
     68 tcp
      5 udp
1
  • This was the answer i ended up coming with you, thank you :)
    – Voiletta
    Apr 4, 2021 at 8:39
-1

The solution i came up with was the following;

ls /proc/sys/net/ipv4 | grep "tcp\|udp" | cut -d "_" -f1 |sort |uniq -c > output.txt

Thanks Everyone for your help :)

2
  • You will get an error if you run this command: uniq: output.txt/: No such file or directory. You could also make it shorter: ls /proc/sys/net/ipv4 | grep -oE "tcp|udp" |sort |uniq -c, but neither solution counts files, but lines of output from grep. In the most general case, these are not the same thing (when there's newlines in filenames).
    – Kusalananda
    Apr 4, 2021 at 9:39
  • thanks i missed the > in my answer. Its counting the files i need it to and output :)
    – Voiletta
    Apr 5, 2021 at 7:00

You must log in to answer this question.

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