tac (reverse-line cat)

Dan Bernstein bernsten at phoenix.Princeton.EDU
Wed Mar 15 07:15:19 AEST 1989


In article <18706 at adm.BRL.MIL> rbj at nav.icst.nbs.gov (Root Boy Jim) writes:
> sed -e '1{;h;d;}' -e '$!{;G;h;d;}' -e '$G'

As you point out, this is limited by sed's buffer limit of 4096 characters.

>                        An awk script would be a better way to do this.

I hate awk, and nobody else has presented an ed version, so here goes:

  #!/bin/sh
  # Reverse the lines of the input. Missing final newline deletes last line.
  cat $* > /tmp/tac$$
  ed - /tmp/tac$$ << EDCMDS
  1,\$g/.*/m0
  1,\$p
  EDCMDS
  rm -f /tmp/tac$$

> Tail -r seems to be the best buggestion

On this system, tail's buffer is 4096 characters, not much bigger than
sed's.

>                                         unless you are reversing
> really BIG files. In that case you probably do want to write a C
> program. There's just no escaping the buffering problem.

If you don't feel like writing or procuring a C version of tac, try the
ed script above. It does a perfectly good job of reversing many-megabyte
files.

The only real problem with using these built-in utilities is that they
can't handle a missing final newline. If the final line lacks a newline,
all the examples given so far will omit that line. When your input is
short enough to use tail -r, you're safe because tail -r adds an extra
newline---but that means it's not truly reversible. On the other hand,
if all you care about is getting the lines reversed and the number of
extra newlines is irrelevant, just add an

  echo '' >> /tmp/tac$$

to the ed script above and you're home free.

---Dan Bernstein, bernsten at phoenix.princeton.edu



More information about the Comp.unix.questions mailing list