Reverse Text Lines Safely with rev

Piping text through rev flips every line back to front in an instant, no scripting required. You will reverse the characters in each line of a text stream, save the result without overwriting the input, and verify what happened. The examples use rev from util-linux 2.39.3, the version installed on the reference machine.

Allow about ten minutes. You need a shell and the util-linux package. All normal examples are unprivileged: do not use sudo just to read a file or write output in a directory you own.

1. Check the installed command

Confirm which executable your shell will run and check its version:

$ command -v rev
/usr/bin/rev
$ rev --version
rev from util-linux 2.39.3

The command accepts zero or more input files. With no file arguments it reads standard input. It writes the reversed lines to standard output, so a terminal command can display results, while redirection or a pipeline can save or process them.

Checkpoint: if command -v rev finds nothing, install or repair util-linux through your normal distribution process. This guide does not require an elevated command once rev is available.

2. Reverse text from standard input

Use a quoted string with printf for a small, repeatable test:

$ printf '%s\n' 'alpha' 'beta' | rev
ahpla
ateb

rev reverses the character order on each line. It does not reverse the order of lines, and it does not join separate lines. The newline remains the line separator, which is why the two outputs appear in the same order as the inputs.

Do not use echo for tests where trailing newlines or backslash handling matter. printf makes the input precise and avoids shell-specific echo behaviour.

3. Reverse a file into a new file

Read an existing file and redirect standard output to a different destination:

$ rev /path/to/input.txt > /path/to/reversed.txt
$ printf 'status: %s\n' "$?"
status: 0
$ sed -n '1,3p' /path/to/reversed.txt
eno
owt
eerht

Replace the paths with files you can read and write. The input file is not modified. The output contains one reversed line for each input line, including an empty line if the input has one.

Safety boundary: shell redirection with > truncates an existing destination before rev starts. If that destination contains anything useful, do not point the example at it.

4. Replace an output only after checking it

When you need to produce a replacement, write a temporary sibling first and move it into place only after the command succeeds:

$ rev /path/to/input.txt > /path/to/reversed.txt.new
$ test "$?" -eq 0 && test -s /path/to/reversed.txt.new
$ mv /path/to/reversed.txt.new /path/to/reversed.txt

The test -s check expects a non-empty result. Do not use it when an empty input is a valid result, because an empty output will then correctly stop the workflow. If either check fails, leave the existing destination alone and inspect the error.

Recovery is simple while the temporary file is still separate: remove only /path/to/reversed.txt.new after confirming its exact path. If mv has already replaced the destination, restore it from your backup or version control. rev itself has no undo operation.

5. Process several files in order

Pass more than one file when their contents should be treated as one output stream:

$ rev /path/to/part-a.txt /path/to/part-b.txt > combined-reversed.txt
$ sed -n '1,4p' combined-reversed.txt
eno
owt
eerht
ruof

The files are read in the order supplied. rev does not add a separator between files, so a file that does not end with a newline can run directly into the first line of the next file before reversal is applied to the combined line. Check the inputs with tail -c 1 if that boundary matters:

$ tail -c 1 /path/to/part-a.txt | od -An -tx1
 0a

A final byte of 0a is a newline. If it is absent, fix the source or process the files separately rather than assuming that the boundary will be invented.

6. Use NUL-delimited records when lines are not enough

The installed manual documents -0 or --zero for input whose records are separated by the NUL byte instead of a newline. This is useful when a record may contain an ordinary newline. Each NUL-delimited record is reversed, and the NUL separator is retained:

$ printf 'alpha\0beta\0' | rev --zero | od -An -tx1c
 61  68  70  6c  61  00  61  74  65  62  00
  a   h   p   l   a  \0   a   t   e   b  \0

Use the option only when both sides of the pipeline agree on NUL delimiters. Sending newline-delimited text to a NUL-delimited command leaves the whole stream as one record, which can produce an unexpected result. The short and long spellings are equivalent on util-linux 2.39.3.

7. Check character handling and failure cases

rev is characterwise rather than a byte-swapping tool. For example, the installed command keeps the UTF-8 coffee-cup character together:

$ printf '%s\n' 'café ☕' | rev
☕ éfac

The manual describes an in-memory buffer for a whole wide-character line. A very long input record without line breaks can therefore require a large allocation and may fail. If you are processing generated or untrusted data, keep records bounded where possible instead of feeding an unbounded single line.

For a missing or unreadable file, check the path and permissions without changing anything:

$ test -r /path/to/input.txt && echo readable
$ rev /path/to/input.txt > /tmp/reversed-check.txt
rev: cannot open /path/to/input.txt: No such file or directory
$ printf 'status: %s\n' "$?"
status: 1

The exact diagnostic can vary with the filesystem and locale. The useful checks are that the input exists, is readable, and that the command status is zero before you trust the output. If a redirected output file was created during a failed run, inspect it before removing it; it may be incomplete.

Done means