Копировать предыдущую строку в текущую строку из текстового файла

В файле конфигурации вы указали два шаблона для файлов журнала в / var / log / glusterfs / bricks каталог:

  1. *. Log
  2. *. Log. *

Второй из этих шаблонов будет соответствовать любому повернутому файлу журнала. Вот почему вы получаете файлы с кажущимися бесконечными суффиксами .1 .

Файлы журнала не сжимаются, поскольку в конфигурации есть delaycompress . Они будут сжаты при следующем повороте.Обратите внимание, что первая проблема (вращение уже повернутых бревен из-за второго вышеупомянутого шаблона) эффективно отключает любое сжатие, поскольку все вращения являются «первым» вращением.

Файлы журнала меняются, если их размер превышает 100 МБ, в соответствии с вашей конфигурацией. Есть один файл большего размера. Он вращается при каждом вызове и никогда не сжимается из-за вышеупомянутой проблемы со вторым шаблоном файла журнала выше.

Есть пустые лог-файлы. Это просто еще один следствие ошибочного шаблона сопоставления файлов журнала, описанного выше. При ротации файла журнала он копируется в имя-файла.log.1 , а исходный файл имя-файла.log усекается («очищается»). . Опять же, из-за шаблона *. Log. * в конфигурации файл имя-файла.log.1 будет скопирован в имя-файла. .log.1.1 при следующей ротации, а исходный имя-файла.log.1 будет усечен.

Это все работает, но поскольку шаблон файла журнала принимает не только фактические файлы журнала, но также и повернутые файлы журнала, в конечном итоге вы получаете беспорядок.

7
02.05.2019, 16:07
7 ответов

Использованиеawk:

awk 'prev{ print prev ";" $0 }
     { prev = $0 }
     END { if (NR) print prev ";" }'

что с учетом вашего ввода дает

A;B
B;C
C;
18
27.01.2020, 20:13

Быстрый и грязный способ (предполагает двойное чтение файла):

$ tail -n+2 file | paste -d';' file -
A;B
B;C
C;
16
27.01.2020, 20:13

Та же основная идея, что и у решения awk, предложенного Торином:

$ perl -lne 'print "$last;$_" if defined $last; $last=$_;END{print "$last;" if $.}' file 
A;B
B;C
C;

Или, если вы любите краткость,:

$ perl -lne'$.>1?print"$l;$_":1;$l=$_}{print"$l;"if$.' file 
A;B
B;C
C;
5
27.01.2020, 20:13
$ sed 'x;G;s_\n_;_;1d;${p;x;s_$_;_;}' file
A;B
B;C
C;

Что делает это sedвыражение:

  • x:сохранить входящую строку в ячейке и получить предыдущую
  • G:добавить новую строку (из пробела )к старой
  • s_\n_;_:заменить разрыв строки -на ;.
  • 1d:если это первая строка, удалить ее (не печатать )и перейти к следующей
  • ${...;}:если это последняя строка...
  • p:сначала вывести соединенную пару
  • x:получить последнюю строку
  • s_$_;_:добавить окончательную;
8
27.01.2020, 20:13

Несколько более простое sedрешение без пробела:

sed '$!N;y/\n/;/;p;y/;/\n/;D' file
  • $!Nдля присоединения к следующей строке (если есть; $!не требуется с GNU sed, если не в режиме POSIX)
  • y/\n/;/заменить новую строку на;
  • pвывести полученную строку
  • y/;/\n/, чтобы вернуться к новой строке, поэтому с помощью
  • Dвы можете избавиться от первой строки и перейти к следующей
6
27.01.2020, 20:13
$ perl -lp -0777e 's/\n(?=(.*\n?))/;$1/g'  input.txt
2
27.01.2020, 20:13

Решение Vim

Можно выполнить эту команду (благодарим Conspicuous Compiler за предложение этого):

vim "+%s/\n\(.\+\)*/;\1\n\1" sample.txt

В качестве альтернативы и, возможно, более привычного варианта, запустите Vim, откройте файл и введите команду ex:

:%s/\n\(.\+\)*/;\1\n\1

Пояснение:

Замена шаблона:

  • символ новой строки,\n
  • группа символов, \(.+\), которая составляет всю следующую строку. Последующий квантификатор *просто указывает, что совпадений может быть ноль или больше
  • .

со следующими:

  • точка с запятой
  • , за которым следует ссылка на группу символов,\1
  • , за которым следует символ новой строки,\n
  • , за которым следует вторая ссылка на группу символов, \1.

До:
enter image description here

После:

enter image description here

5
27.01.2020, 20:13

Теги

Похожие вопросы