опция команды tac создает странный вывод

опция команды tac создает странный вывод

Допустим, у меня есть файл, содержащий только

a
b
c
b
a

Используя tac --separator=a fileBASH [на базе Linux на базе Debian], я получаю следующее:

                  # empty line
                  # empty line
b
c
b
aacommand@prompt  # two a just before the prompt


Вопрос: Насколько я понял, --separator=aопределяет, что aобозначает разрыв внутри строки, а не newline.Это правильно?

Я пробовал это с другими строками, гораздо большим вводом, и в итоге получил довольно беспорядок. Все остальные варианты работают вполне правильно, я полагаю: Если я использую, то tac --beforeсначала получаю около пяти, а не одну пустую строку, но затем это то, что должно произойти, верно?

решение1

tacпроще понять в случае, для которого он изначально предназначен, то есть когда разделитель является терминатором записи, т. е. разделитель появляется после последней записи. Он печатает записи (включая каждый терминатор) в обратном порядке.

$ echo -n fooabara | tac -s a; echo
rabafooa

Входные данные состоят из трех записей ( foo, bи r), за каждой из которых следует разделитель a; выходные данные состоят из трех записей ( r, bи foo), за каждой из которых следует разделитель a.

Если последняя запись не заканчивается символом конца записи, она все равно печатается первой, без разделителя записей.

$ echo -n fooabar | tac -s a; echo
rbafooa

Последняя запись rв итоге объединяется с предпоследней записью bбез какого-либо разделителя между ними, поскольку в конце последней записи разделителя не было.

Ваш ввод выглядит немного более запутанным из-за новых строк. Давайте посмотрим, как это выглядит с запятыми вместо новых строк:

$ echo -n a,b,c,b,a, | tac -s a; echo
,,b,c,b,aa

Есть три входных записи: пустая (с терминатором a), объемная ,,b,c,b,(снова с терминатором) и незавершенная ,в конце. Эти записи (каждая со своим терминатором, за исключением последней записи, у которой нет терминатора) печатаются в обратном порядке.

Ваша путаница, вероятно, возникла из-за того, что вы ожидали, что «разделитель» будет разделителем, но это неверное название: на самом деле это ограничитель записи. --beforeделает его инициатором.

решение2

Следующий пример может помочь использовать эту --regexопцию:

$ cat records 
---1---
1
2
3
---2
A
B
C
---3--
a
b
c
$ tac --before --regex --separator=^---[0-9]+-*$ records
---3--
a
b
c
---2
A
B
C
---1---
1
2
3

В этом примере файл recordsсодержит многострочные записи, каждая из которых начинается со строки ( ^...$), которая начинается с ---, за которой следует число ( [0-9]+) и необязательная последовательность знаков минус ( -*). Видно, что порядок строк в каждой записи и ее строка заголовка сохранены.

Я использую tacэтот способ для отображения записей в файлах журнала в обратном порядке, как это используется в приложениях-лентах, таких как Twitter. Например, чтобы напечатать только две последние записи в обратном порядке:

tac --before --regex --separator=^---[0-9]+-*$ example \
 | awk '/^---[0-9]+-*$/ {c++} c>2 {exit}{print}'

Связанный контент