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.
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.
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.
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.
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.
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.
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.
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.
rev --version identifies the installed util-linux command.mv changes the destination.