0

How would I start off using get-opts? The output should be similar to this, but I need the filter that is a taken input from standard input

  awk < /var/log/messages '{ print $2, $1, $5}' | uniq -c | awk '{ print $2, $3, $1, $4 }' | cut -d':' -f1
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • If you need good answers I would recommend posting some sample input data and your desired output. `awk` is very powerful and can easily remove the need of extra pipes, but you need to show what you want exactly. – jaypal singh May 22 '14 at 04:33

1 Answers1

0

If you write a shell script, then the normal answer is to use "$@", which is somewhat magical:

#!/bin/bash
awk '{ print $2, $1, $5}' "$@" |
uniq -c |
awk '{ print $2, $3, $1, $4 }' |
cut -d':' -f1

The "$@" represents 'all the command line arguments', or nothing if there are no command line arguments. Given that awk is a command that reads the files named on its command line, or standard input if no files are specified, this will work correctly — it is an important part of the design of good, general purpose, Unix tools. If you want to process /var/log/messages in the absence of a command line argument, then you need to use the shell parameter expansion notation:

"${@:-/var/log/messages}"

If there are no arguments in the argument list, then it substitutes /var/log/messages as the file name.

You can find out more about "$@" in the Bash manual under Special Parameters. See also How to iterate over the arguments in a Bash script.

Note that uniq does not sort the data; it looks for lines that are adjacent and the same. You would usually insert a sort before uniq -c:

#!/bin/bash
awk '{ print $2, $1, $5}' "$@" |
sort |
uniq -c |
awk '{ print $2, $3, $1, $4 }' |
cut -d':' -f1
Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278