The 'env' command prints out all of the environment variables and their values.
Come up with a command that prints a list of environment variables whose names
end with either 'NAME', 'DIR' or 'PATH'.
What I've tried.
$ env | grep '[NAME, DIR, PATH]'
Although it highlights the part of the variables it does not list them as it should. It actually prints the whole lines including the variables. Not sure what I'm missing.
University Of Technology Sydney, Unix Systems Programming
In a regular expression (RE) the ^ means the beginning of the line; together with the = it enforces an exact match. Omit the ^ and it must only end with the given pattern.
$1 ~ /.*(NAME$|DIR$|PATH$)/ is correct, because the $1 field is = delimited, and in a RE the $ enforces the end of the field. The .* means any characters but is not needed here because any leading characters are always permitted in a RE (unless there is a ^ anchor). So it is optimized $1 ~ /NAME$|DIR$|PATH$/ or with a common $ anchor $1 ~ /(NAME|DIR|PATH)$/ .
We already did. The BEGIN block, running before everything else, sets the field separator as =. Then the expression tells AWK to print all lines where the first field, $1, matches the given regex.
You could, kind of, sort of use grep, depending on if your system has egrep for all the bits and pieces that made solving the problem in awk easy; but even if you have extended support, it would be more awkward since it doesn't have columns like awk does. Why not use a tool that has all the right things available by default and is much simpler to use?
Assuming that you have submitted you homework by now... and expanding a bit on what Corona688 already said...
The command:
env | awk -F= '$1 ~ /(NAME|DIR|PATH)$/{print $1}'
tells awk to read the output produced by env , to split each line it reads into fields separated by the = character, and then look at the first field in each line. If, and only if, that first field ends with one of the three strings you're looking for, it prints the contents of the first field on that line. It then goes on to process the next line of input from env .
You could come close to what you want with egrep using:
env | egrep -o '^[!=]*(NAME|DIR|PATH)='
which with my current environment would give you:
CDPATH=
LOGNAME=
PATH=
TMPDIR=
XPC_SERVICE_NAME=
but then you would have to post-process the output to get rid of the = that you don't want to print. You could easily do that with a second grep or egrep , but it is much more efficient to invoke awk once instead of egrep and another grep or egrep .
If you do decide to use two grep s instead of awk , note that you can do it with two invocations of grep without using egrep at all (and grep is frequently slightly smaller and faster than egrep , but this can vary from operating system to operating system):
In the above, the first grep throws away everything on each line starting with the first = found on each line of output from env and the second grep throws away any lines that don't end with one of the three strings you're searching for.