Как добавить разрыв строки после каждой пятой точки с запятой (;) в текстовом файле

Я вижу, что ответ пользователя steeldriver уже принят, но я решил предложить то, что я считаю более коротким, простым и удобным для чтения вариантом. По крайней мере, он демонстрирует некоторые другие особенности awk (, и ОП всегда может передумать ):

.
awk '
  { gsub(","," ")
    $0=gensub("([[:upper:]])([[:digit:]])","\\1 \\2","g")
    $0=gensub("([[:lower:]])([[:upper:]])","\\1 \\2","g")
    print
  }' file.csv
4
05.03.2020, 17:13
4 ответа

С trиpaste

tr ';' '\n' < semicolons | paste -d';' - - - - -

Тесты

$ cat semicolons
a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a

$ tr ';' '\n' < semicolons | paste -d';'  - - - - -
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a
a;a;a;a;a

И tr, иpasteуказаны в стандарте POSIX.

Чтобы добавить требуемую точку с запятой ;в конце строк

tr ';' '\n' < semicolons | paste -d';' - - - - - | sed s/$/\;/

Тесты

$ tr ';' '\n' < semicolons | paste -d';' - - - - - | sed s/$/\;/
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;    
18
28.04.2021, 23:21

Чисто с использованием замены GNU sed:

sed 's/\(\([^;]*;\)\{5\}\)/\1\n/g'

или без всех экранирующих обратных слэшей с использованием-E(спасибо @JoL):

sed -E 's/(([^;]*;){5})/\1\n/g'

Пример:

$ cat test.txt
a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a;a; etc......

$ cat test.txt | sed 's/\(\([^;]*;\)\{5\}\)/\1\n/g'
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a;a;
a;a;a;a; etc......

Пояснение:

  • \([^;]*;\):Группа захвата регулярных выражений, соответствующая всем символам до точки -двоеточия включительно.
  • \(\([^;]*;\)\{5\}\):Группа захвата регулярных выражений, соответствующая пяти вхождениям вышеперечисленного. В команде sedэто будет соответствовать \1.
  • s/\(\([^;]*;\)\{5\}\)/\1\n/g:заменить(s/)каждое вхождение(/g)группы из пяти вхождений всех символов до точки с запятой(\(\([^;]*;\)\{5\}\))включительно с самим собой (\1), но за которым следует символ новой строки(\n).
13
28.04.2021, 23:21

В методе редактора Sed мы помещаем новую строку после 5-й точки с запятой, печатаем до новой строки, удаляем до новой строки, стираем и повторяем, пока не закончится пространство шаблона.

$ sed -e 's/;/;\n/5;P;D' file 

В Perl используйте точку с запятой в качестве разделителя полей и печатайте группами по 5 точек с запятой как OFS и пустым полем в конце, чтобы напечатать завершающую точку с запятой:

$ perl -F\; -lane '$,=";";
     print splice(@F, 0, 5), q() while @F;
' file 

Используя Awk, мы просматриваем группу из 5 полей и добавляем точку с запятой к первым 4 и точку с запятой + новую строку к пятому. Затем напечатайте поля, разделяя их нулем:

$ awk -F\; -vOFS= '{
        for(i=1; i<=NF; i++)
            $(i) = $(i) (i%5 ? FS : FS RS)
  }1' file
5
28.04.2021, 23:21

Я считаю, что, хотя регулярные выражения подходят для такого рода задач, я всегда делаю это с помощью макросов текстового редактора для наглядности и простоты.

Используя vim, вы можете

set textwidth=20

или аналогично низкий и

set wrap

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

qqf;f;f;f;f;i\n99999@q

сделает это.

0
28.04.2021, 23:21

Теги

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