3

For instance, less allows you to read line by line, starting from the beginning. Is there a similar utility or line that could be run in the terminal that could display a file backward character by character? If not, how about a "cat" like utility that displays the entire file backward by character?

6

this does it :

cat /tmp/aa | tac | rev

where tac reverses file line by line keeping chars intact ... then rev finishes it off by simply reversing chars of each given line leaving line by line intact .. so for example :

cat /tmp/aa 


Is there a way to read characters backwards from the end of a file in the terminal?

For instance, less allows you to read line by line, starting from the beginning. Is there a similar utility or line that could be run in the terminal that could display a file backward character by character?



cat /tmp/aa | tac | rev


retcarahc yb retcarahc drawkcab elif a yalpsid dluoc taht lanimret eht ni nur eb dluoc taht enil ro ytilitu ralimis a ereht sI .gninnigeb eht morf gnitrats ,enil yb enil daer ot uoy swolla ssel ,ecnatsni roF

lanimret eht ni elif a fo dne eht morf sdrawkcab sretcarahc daer ot yaw a ereht sI
  • 4
    Nice answer but cat here is excessive: tac /tmp/aa | rev – kos Oct 30 '15 at 4:14
  • 4
    Indeed, tac can print lines in reverse more efficiently if you provide the file as an argument, since it can seek backwards through the original file instead of having to copy it into a temporary buffer. Also, combining tac | rev isn't exactly the same as printing the file backwards character-by-character; it effectively moves a newline from the end of the file to the beginning before reversing it. – Miles Oct 30 '15 at 7:23
3

You can use GNU tac alone to read a file backwards character-by-character, by specifying a "record separator" that matches every character:

# Reverse a file character by character.
# From http://www.gnu.org/software/coreutils/tac
tac -r -s 'x\|[^x]' input_file

-s specifies a custom record separator (instead of newline) and -r treats the separator string as a regular expression.

This is different from the answers using tac | rev, because it actually reverses the order of characters in the file, including newlines, and works correctly even if the last line doesn't end in a newline.

% printf 'Hello\nworld\n' | tac | rev | xxd
0000000: 646c 726f 770a 6f6c 6c65 480a            dlrow.olleH.

% printf 'Hello\nworld\n' | tac -r -s 'x\|[^x]' | xxd
0000000: 0a64 6c72 6f77 0a6f 6c6c 6548            .dlrow.olleH
  • This is great answer, I didn't know you could specify a record separator for tac. While x\|[^x] indeed works, it seems a little silly to use it when you have a metacharacter to match any character made on purpose: tac -r -s '.' input – kos Oct 30 '15 at 7:59
  • 1
    Ah sorry, obviously . doesn't match newlines. Hats off, great answer. – kos Oct 30 '15 at 8:08
1

There’s a utility called tac from the GNU coreutils package. It’s a line-based program so it prints each line to standard output, last line first – as opposed to each character.

The rev command (from the util-linux package) is character-based and it prints each line to standard output, reversing the order of characters in every line.

0

Two different approaches using Perl:

1:

perl -e 'while($c=getc){$s=$c.$s};print($s)' <input

2:

perl -F'' -0777ae 'print(reverse(@F))' <input

1:

  • -e: executes the following argument;
  • while($c=getc){$s=$c.$s}: stores the return value of getc in $c and prepends $c to $s until the return value of $c is not undefined;
  • print($s): prints $s.

2:

  • -F'': unsets the input field separator (this makes Perl split fields on any character);
  • -0777ae: sets the input record separator to an invalid character (this prevents Perl from splitting records), splits the fields of the input storing them into F and executes the script passed as an argument;
  • print(reverse(@F)): prints the elements of an array containing the elements of F in a reversed order;
% cat input
For instance, less allows you to read line by line, starting from the beginning.
Is there a similar utility or line that could be run in the terminal that could display a file backward character by character?
If not, how about a "cat" like utility that displays the entire file backward by character?
% perl -e 'while($c=getc){$s=$c.$s};print($s)' <input

?retcarahc yb drawkcab elif eritne eht syalpsid taht ytilitu ekil "tac" a tuoba woh ,ton fI
?retcarahc yb retcarahc drawkcab elif a yalpsid dluoc taht lanimret eht ni nur eb dluoc taht enil ro ytilitu ralimis a ereht sI
.gninnigeb eht morf gnitrats ,enil yb enil daer ot uoy swolla ssel ,ecnatsni roF
% perl -F'' -0777ae 'print(reverse(@F))' <input

?retcarahc yb drawkcab elif eritne eht syalpsid taht ytilitu ekil "tac" a tuoba woh ,ton fI
?retcarahc yb retcarahc drawkcab elif a yalpsid dluoc taht lanimret eht ni nur eb dluoc taht enil ro ytilitu ralimis a ereht sI
.gninnigeb eht morf gnitrats ,enil yb enil daer ot uoy swolla ssel ,ecnatsni roF

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.