Отделить несколько разделов/строк от файла

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

$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Как это работает

  • -v RS='[,\n]'

    Это говорит awk использовать любое вхождение запятой или новой строки в качестве разделителя записей.

  • a=$0; getline b; getline c

    Это указывает awk сохранить текущую строку в переменной a, следующую строку в переменной bи следующую строку после этой в переменной c.

  • print a,b,c

    Это говорит awk печатать a, bи c

  • .
  • OFS=,

    Это говорит awk использовать запятую в качестве разделителя полей при выводе.

Использование trиpaste

$ tr, '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Как это работает

  • tr, '\n' <filename

    При чтении из имени файла все запятые преобразуются в символы новой строки.

  • paste -d, - - -

    Это pasteдля чтения трех строк из стандартного ввода (по одной для каждой-)и вставки их вместе, разделенных запятой(-d,).

Альтернативный awk

$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Как это работает

  • -v RS='[,\n]'

    Это говорит awk использовать любое вхождение запятой или новой строки в качестве разделителя записей.

  • printf "%s%s",$0,(NR%3?",":"\n")

    Это указывает awk напечатать текущую строку, за которой следует либо запятая, либо новая строка, в зависимости от значения номера текущей строки, NR, по модулю 3.

1
07.02.2020, 14:11
3 ответа

Используется редактор файлов ed, но для этого требуется, чтобы второй (пустой )файл был создан заранее. В этом примере исходный файл называется file1.

Создайте второй файл с именемfile2

> file2

Хередок

ed -s file1 << 'EOF'
H
g/^THAT($/;/^.*\;$/d
w
u
g/^THIS($/;/^.*\;$/d
0r file2
w file2
EOF

Первая строка, которая передает file1в edс помощью heredoced -s file1 << 'EOF'

Вторая строка выводит более подробные сообщения, полезные при ошибках.H

Третья строка Удалить строки, начинающиеся с THAT (до строки, заканчивающейся символом ;

g/^THAT($/;/^.*\;$/d

Четвертая строка Записать изменения в файл1w

Пятая строка Отменить изменения ТОЛЬКО в буфере, а не в файле1.u

Шестая строка Удалить строки, начинающиеся с ЭТОГО (до строки, заканчивающейся символом ;

g/^THIS($/;/^.*\;$/d

Седьмая строка Добавить оставшийся текст в буфере в начало файла2

0r file2

Восьмая строка Записать файл изменений2.w file2


Один вкладыш.

>file2; printf '%s\n' H 'g/^THAT($/;/^.*\;$/d' w u 'g/^THIS($/;/^.*\;$/d' '0r file2' 'w file2' | ed -s file1

Обратите внимание, что edредактирует файл in-place, что означает, что файлы будут редактироваться напрямую, и вывод не будет распечатываться где-то еще, поэтому сначала протестируйте его на нескольких примерах, прежде чем запускать edв рабочем файле.

0
28.04.2021, 23:24

С любым awk:

$ awk -v RS=';' 'NF{sub(/^\n/,""); print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line)
THIS(
is third
line)

$ cat second_file
THAT(
is second line)
THAT(
is
fourth
line)

или с помощью GNU awk для мульти -символов RS и RT:

$ awk -v RS='(THIS|THAT)[^;]+;\n' -v ORS= '{$0=RT; print > (/^THIS/ ? "first_file" : "second_file")}' file

$ cat first_file
THIS(
is first
Line);
THIS(
is third
line);

$ cat second_file
THAT(
is second line);
THAT(
is
fourth
line);

Оба решения предполагают, что ваш пример точен, и у вас никогда не будет ;s, кроме как в конце блоков (, например. не входит в (...)части ).

1
28.04.2021, 23:24

Попытка использовать метод флага Awk

awk '/THIS/{f=1}/THAT/{f=0}f' file > file1(Contains "THIS" PATTERN)
awk '/THAT/{f=1}/THIS/{f=0}f' file > file2(Contains "THAT" PATTERN)

выход

cat file1

THIS(
is first
Line);
THIS(
is third
line);



cat file2

    THAT(
    is second line);
    THAT(
    is 
    fourth
    line);
0
28.04.2021, 23:24

Теги

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