Excluding a long list of words with grep This Bash program extracts the 20 first lines of each man page present on a system and uses grep to remove lines matching a list of selected terms.

How can I improve the grep part? (something less repetitive, with less pipe but that do the same job)

#!/bin/bash

# generate the list
compgen -c &gt; man

# extract each man of the list                                                                                                          
while read -r LINE; do
MANWIDHT=80 man "$LINE" | head -20 | grep -v NAME | grep -v 1 | grep -v SYNOPSIS | grep -v SYNOPSYS | grep -v OVERVIEW | grep -v VERSION | grep -v VERSION | grep -v INTRODUCTION | grep -v 5 | grep -v ABSTRACT | grep -v 4 | grep -v DESCRIPTION | grep -v COPYRIGHT | grep -v ABRT | grep -v SEE | grep -v 8 | grep -v case | grep -v 2 | grep -v STATUS | grep -v CHECK | grep -v UNIX | grep -v FORTUNE | grep -v PROLOG | grep -v Usage | grep -v Help | grep -v Introduction | grep -v Local | grep -v ARGUMENTS | grep -v SYNTAX | grep -v NOTE | grep -v QUERYING | grep -v 3 | grep -v Description | grep -v Note | grep -v Name | grep -v COPYING | grep -v COMMAND | grep -v USAGE | grep -v EXAMPLE | grep -v 3 | grep -v OPTIONS | grep -v AUTHOR | grep -v DOCUMENTS | grep -v SUMMARY | grep -v -e '^$' &amp;&amp; echo -en '\n'
done &lt; man &gt; man1

# add the % to each empty line                                                                                                          
sed -i -e 's/^$/%/' man1

# merge to fortune-rtfm db                                                                                                              
cat man1 &gt; fortune-rtfm
First of all, avoid excessively long lines that force reviewers to scroll horizontally far far right. You can break lines to manageable length like this:

MANWIDHT=80 man "$LINE" | head -20 | grep -v NAME | grep -v 1 | \
grep -v SYNOPSIS | grep -v SYNOPSYS | grep -v OVERVIEW | grep -v VERSION | \
grep -v VERSION | grep -v INTRODUCTION | grep -v 5 | grep -v ABSTRACT | \
...


You are using too many temporary files. You could chain the commands together in a single pipeline, without unnecessary temporary files:

compgen -c | while read -r LINE; do
    MANWIDHT=80 man "$LINE" | head -20 | grep -v NAME | ...
done | sed -e 's/^$/%/' &gt; fortune-rtfm


Instead of a chain of grep -v word1 | grep -v word2 | grep -v word3,
you can use a single grep with multiple -e parameters like this:

grep -v -e word1 -e word2 -e word3


A single grep process instead of dozens will certainly run much faster.

A simple echo is the same as echo -en '\n', but better in every way.

Finally, instead of a long grep with all the terms you want to exclude, you can put them in a file, one word per line, and use the -f flag of grep to use that list. Then the script can be shortened to:

#!/bin/bash

compgen -c | while read -r LINE; do
    MANWIDHT=80 man "$LINE" | head -20 | grep -v -f words.txt | grep -v '^$' &amp;&amp; echo
done | sed -e 's/^$/%/' &gt; fortune-rtfm


@Sundeep pointed out a few important things in a comment. MANWIDHT is misspelled, it should be MANWIDTH.
Also, since the patterns are fixed strings (as opposed to regular expressions), it's good to add the -F flag so that grep can optimize the matching. Lastly, you might want to match whole words instead of parts of words. If that's the case, add the -w flag. This is equivalent to wrapping each pattern within \&lt;...\&gt;. (The effect is that for example "VERSIONING" is matched by grep VERSION, but by grep -w VERSION.)

The content of words.txt, sorted for easier reading, is something like this (just the first bunch of lines):

1
2
3
4
5
8
ABRT
ABSTRACT
ARGUMENTS
AUTHOR
CHECK
COMMAND
COPYING
... (and so on)


If you want to keep all the patterns inside your script file, you can do that too, for example like this:

compgen -c | while read -r LINE; do
    MANWIDHT=80 man "$LINE" | head -20 | grep -vFf &lt;(cat &lt;&lt; EOF
1 2 3 3 4 5 8 
ABRT ABSTRACT ARGUMENTS AUTHOR 
CHECK COMMAND COPYING COPYRIGHT 
DESCRIPTION DOCUMENTS Description 
EXAMPLE 
FORTUNE 
Help 
INTRODUCTION Introduction 
Local 
NAME NOTE Name Note 
OPTIONS OVERVIEW 
PROLOG 
QUERYING 
SEE STATUS SUMMARY SYNOPSIS SYNOPSYS SYNTAX 
UNIX USAGE Usage 
VERSION 
case 
EOF
) | grep -v '^$' &amp;&amp; echo
done | sed -e 's/^$/%/' &gt; fortune-rtfm