ONLY(1)

NAME
only - an advanced filter for words, lines, and more

SYNOPSIS
only [-[bcwlf] EXPR ] ... file ...

DESCRIPTION
Only is an advanced filtering tool, like grep, but instead of filtering only on lines, it can also filter on characters or words, called tokens in general. When tokens match, there are two options that allow for greater control than grep. They can appear before and/or after a regex and are called absolute indices and relative indices, respectively. Absolute indices refer to matches, whereas relative indices refer to tokens, with the match being token zero. For example, -l N/regex/M will show the M-th line after the N-th occurance of regex.

For a more detailed description, see below.

OPTIONS

(-b|--bytes)=EXPR
    Byte mode

(-c|--chars)=EXPR
    Character mode

(-w|--words)=EXPR
    Word mode

(-l|--lines)=EXPR
    Line mode

(-f|--files)=EXPR
    File mode

EXTENDED DESCRIPTION
The original goal of 'only' was to combine the features of head, tail, grep, and cut into a single utility that was capable of all of their features, but with the power to do so much more. For example, head and tail are good for selecting the first n-lines or last n-lines of a file, but what if you want lines 10-30? Neither utility would be very good alone, and combining them to accomplish your goal would be a nightmare. Granted, one could probably construct a one liner in awk or perl to achieve the desired effect, but at the expense of clarity.

To overview the features of only, there are two major kinds of inputs: files and modes. A file can either be a filename or '-' which means standard input. The modes currently supported are: bytes, characters, words, lines, and files. The difference between each mode is what the pattern /^.*$/ will match. When no pattern is given, and a number is given instead, then it will refer to the appropriate token type, for example, the first word, the second line, etc.

In byte mode, the input is broken up into 8-bit octets, so the patterns must only match a single byte. In character mode, the input is broken up according to the specified encoding (or UTF-8 if unspecified), where each character may be multiple bytes. In word mode, the separators can be any white-space, so it tries to remember what separator was there in the beginning, and puts it back before displaying. In line mode, only behaves very similar to grep but with a few extra features. In file mode, the filenames are not shown (unless -F is used) but the entire file is shown if it matches the pattern.

Syntax
Matching expressions are expressions written in a small language that forms a super-set of regular expressions. The syntax of matching expressions are the same regardless of what the current mode is. This is true even of byte mode, where you must write "\xFF" if you want a non-printable character. Matching expressions can be as simple as a number or a word. First, only tries to parse an expression as a number, then as an expression of the form M/regex/N and if that fails, then it treats the entire expression as a regex. Each M and N may be a numeric expression. Numeric expressions have the syntax (in pseudo-Parsec):
  num = [+-][0-9]+
  numeric = sepBy numbers ','
  numbers = num ';' num ':' num # from A to C step (A-B)
          | num ':' num ';' num # from A to B step C
          | num ':' num # from A to B
          | num which means you can specify just a single number (3) or something as complicated as multiple ranges (such as 3:5,100:109). These numeric expressions can occur on either side of the regex, or both sides with a combined effect. The syntax of the entire matching expression is:
  expr = do optional numeric
            c <- punct ; regex ; c
            (try c ; regex ; c ; optional num
               | optional numeric)
       | numeric
       | regex where punct is any ASCII punctuation character except ".,:;", and regex is a POSIX extended regular expression.

Semantics
The semantics of matching expressions are a little harder to describe. However, a generalization of the example given above should hold true:
  "N/regex/M" means the M-th tokens relative to the N-th matches The default for N is 1:-1 and the default for M is 0. The N are known as absolute indices, and the M are known as relative indices. Absolute indices will take the list of matches (the list of tokens that were matched by the regular expression), and apply use the numbers in N as the indices of this list. This gives you the ability to select the first match (1) or the last match (-1). If you use negative numbers, then it will count from the end of file going backwards, so (-2) would be the second to last match. Relative indices will take the list of matches, the original list of tokens, and for each match, it forms a virtual list where 0 refers to the match's index in the list of tokens. This allows one to emulate grep's -A (after) and -B (before) options.

Here are some equivalent command-lines for "after" a match:
  grep -A3 expr file.txt
  only -l/expr/0:3 file.txt Here are some equivalent command-lines for "before" a match:
  grep -B3 expr file.txt
  only -l/expr/-3:0 file.txt Normally, these would be used to select line numbers, like if you got a compiler error in a file with 10 million lines, and you just wanted to see the surrounding text.

FILES
~/.onlyrc
    A user configuration file. [Not implemented yet]