0

i try to figure out how to extract all service names out of /etc/services and send them to text file sort them alphabetically remove any duplicates get rid of any blank lines and unnecessary spaces and have line count

4
  • 1
    Please edit and add what you have so far.
    – dessert
    Mar 10, 2018 at 19:34
  • 3
    I'm writing that because this sounds horribly like an assignment and we're not a scripting service here. In fact all you need is sed, sort, bash redirection and wc. Any real question which shows at least a bit effort is very welcome!
    – dessert
    Mar 10, 2018 at 19:49
  • 2
    i will admit and apologize for that, it is assignment for my linux class i'm taking online. i tried to figure out on my own answer for that but all i have its errors and not proper output. i will show you some of my output but please dont laugh at me, all i ask its to show direction not complete commands
    – Soulrelic
    Mar 10, 2018 at 22:21
  • @Soulrelic Nobody laughs at you (please take my sincere apologies if that's how it looks like, that was in no way our intention), but we can't show you where you're wrong if you don't show us what you've tried and what errors you got. We're happy to help you and explain extensively!
    – dessert
    Mar 10, 2018 at 22:26

3 Answers 3

1

The file /etc/services looks like this:

# Network services, Internet style
#
# (more comments)

tcpmux    1/tcp     # TCP port service multiplexer
echo      7/tcp
...
discard   9/tcp     sink null
discard   9/udp     sink null
...
ssh       22/tcp    # SSH Remote Login Protocol
...

That is, there are

  • lines that consist only of a comment
  • lines with trailing comments
  • empty lines
  • duplicates in the first column

To remove all of them, the following command is one possible way:

awk '!/^\s*$/ && !/^\s*#/ {print $1}' /etc/services | sort -u | cat -n

Output

 1  acr-nema
 2  afbackup
 3  afmbackup
 4  afpovertcp
 5  afs3-bos
 6  afs3-callback
 7  afs3-errors
...

Explanation

awk '!/^\s*$/ && !/^\s*#/ {print $1}' /etc/services

In general, awk reads a given file (or stdin) and then executes the following for each line:

condition_for_a_line { commands_when_condition_is_met }    

We use !/^\s*$/ && !/^\s*#/ as the condition which means line is not empty and line doesn't start with a comment. When both conditions are met, the first column $1 is printed. This gives us all first columns of the file without empty and comment lines.

sort -u

This sorts the data and eliminates duplicates in one go.

cat -n

Simply adds line numbers.

0
1

Here's my sed solution:

</etc/services sed '/^\w/!d;s/\s.*//' | sort -u >out

sed '…' file instead of <file sed '…' is possible but not preferable, as Stéphane Chazelas explains.

This will first eliminate every line beginning with something else than a word character, then delete everything from every line beginning with the first whitespace character, then sort alphabetically and eliminate duplicate lines and finally redirect the output into the file out.

To get a line count of this file, I'd use wc:

<out wc -l

Explanations

  • </etc/services – let bash open the specified file and assigns its content to stdin, it doesn't matter if this redirection is placed before or after the command, you could even do >out sed '…' <in if you like
  • sed '…' – let sed execute the expressions
  • /^\w/!d – don't (!) delete every line beginning (^) with a word character, but every line that doesn't match this criterion
  • s/\s.*// – in every line, substitute the first match of a whitespace character and everything (.*) that follows with nothing (= delete it)
  • command1 | command2 – let bash assign command1's stdout to command2's stdin
  • sort -u – let sort sort the lines alphabetically and output only the first of an equal run (-u or --unique)
  • >out – let bash redirect the stdout to the specified file
  • wc -l – let wc print the newline counts
1
  • 1
    This is cool. I admit I always stumble when I see redirection at unexpected places, i.e. before the actual command instead of after them.
    – PerlDuck
    Mar 11, 2018 at 12:57
-1
awk '{print $1}' /etc/services | grep -v # | uniq | sort > yourFile
5
  • 2
    Wrong order of commands. Put uniq after sort. And the grep will also remove lines with trailing comments.
    – PerlDuck
    Mar 11, 2018 at 8:52
  • sort -u is also available.
    – pa4080
    Mar 11, 2018 at 9:03
  • You probably meant grep -v \#, otherwise this command line doesn't work at all, but even then there are still empty lines as well as double entries in the output – did you test your solution?
    – dessert
    Mar 11, 2018 at 10:47
  • 1
    @dessert Even grep -v \# won't help. I have lines like ssh 22/tcp # SSH … and they would be filtered out.
    – PerlDuck
    Mar 11, 2018 at 11:00
  • dessert, tcsh. For bash grep -v '#' Mar 11, 2018 at 11:09

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