Есть ли способ прочитать символы в обратном направлении от конца файла в терминале?
Например, less позволяет читать построчно, начиная с начала. Есть ли подобная утилита или строка, которая могла бы быть запущена в терминале, которая могла бы отображать файл назад символ за символом? Если нет, то как насчет "кошачьей" утилиты, которая отображает весь файл в обратном порядке?
4 ответа
Это делает это:
cat /tmp/aa | tac | rev
где tac инвертирует файл строка за строкой, сохраняя символы неизменными... затем rev заканчивает его, просто обращая символы каждой строки, оставляя строку за строкой... так, например:
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
Вы можете использовать GNU tac
в одиночку, чтобы прочитать файл обратно символ за символом, указав "разделитель записей", который соответствует каждому символу:
# Reverse a file character by character.
# From http://www.gnu.org/software/coreutils/tac
tac -r -s 'x\|[^x]' input_file
-s
указывает пользовательский разделитель записей (вместо новой строки) и -r
обрабатывает строку-разделитель как регулярное выражение.
Это отличается от ответов, использующих tac | rev
потому что он фактически меняет порядок символов в файле, включая символы новой строки, и работает правильно, даже если последняя строка не заканчивается новой строкой.
% 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
Там есть утилита под названием tac
из GNU coreutils
пакет. Это программа, основанная на строках, поэтому она печатает каждую строку в стандартный вывод, в первую очередь - в отличие от каждого символа.
rev
команда (из util-linux
package) основан на символах и печатает каждую строку на стандартный вывод, изменяя порядок символов в каждой строке.
Два разных подхода с использованием Perl:
1:
perl -e 'while($c=getc){$s=$c.$s};print($s)' <input
2:
perl -F'' -0777ae 'print(reverse(@F))' <input
1:
-e
: выполняет следующий аргумент;while($c=getc){$s=$c.$s}
: сохраняет возвращаемое значениеgetc
в$c
и претендует$c
в$s
до возвращаемого значения$c
не является неопределенным;print($s)
: печать$s
,
2:
-F''
: удаляет разделитель входного поля (это делает поля Perl разделенными на любой символ);-0777ae
: устанавливает для входного разделителя записей недопустимый символ (это предотвращает разбиение записей в Perl), разделяет поля ввода, сохраняя их вF
и выполняет скрипт, переданный в качестве аргумента;print(reverse(@F))
: печатает элементы массива, содержащие элементыF
в обратном порядке;
% 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