sed (или awk): добавить новую строку "commit;" после каждой n-й строки, но только если следующая строка начинается с шаблона

Это то же измерение. 309 Гб — это размер, указанный в степенях двойки (безобразного -имени Гибибайта ), а 331 Гб — это размер, указанный в степенях 10 согласно СИ(Гигабайт).

309 Гб (в степени 2)*1024 *1024 *1024 = 331786223616 байт, т.е. 331 Гб (в степени 10 ).

Как указал @don _crissti, df -hпечатает значения в двоичных степенях. Если бы вы запустили df -H, который вместо этого использует десятичные степени, он напечатал бы 331 Гб используемого пространства.

Для получения дополнительной информации см.https://en.wikipedia.org/wiki/Binary_prefix.

2
03.03.2020, 20:34
3 ответа

Вот пример вставки commitпосле каждой третьей команды INSERT.

sed '0~2{:a;N;/;$/!ba;s/$/\ncommit;/}'

Я предполагаю, что каждая вставка заканчивается на ;в конце строки (вам может понадобиться добавить \s*после ;, если у вас есть строки с пробелами в конце.

Логика состоит в том, чтобы взять 3 строки и проверить, есть ли ;в конце, и объединить другие строки, пока не будет получена строка с ;в конце. И вставьте после этого commit;.

После того, как строка добавлена, она будет продолжена со следующими строками.

Не стесняйтесь изменять количество строк в соответствии с вашими потребностями.

0
28.04.2021, 23:21

Решение в awk, которое берет каждую группу из nстрок(n = 3в примере )и вставляет «фиксацию;» перед последней строкой, если она начинается с «INSERT INTO», будет:

$ awk '{ if (/^INSERT INTO/ && NR%3 == 0) { print "commit;" }; print }' input
0
28.04.2021, 23:21

С любым awk в любой оболочке на каждом компьютере UNIX и при условии, что у вас есть -точки с запятой только в конце строк, когда они находятся в конце каждого оператора INSERT, как в вашем опубликованном образце ввода:

$ awk '{print} /;$/ && !((++c)%2){print "commit;"}' file
INSERT INTO X..... );
INSERT INTO X..... );
commit;
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
commit;
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
commit;
INSERT INTO X..... );

Исходный ответ, когда я слишком много думал над проблемой:

С помощью GNU awk для multi -char RS и при условии, что у вас есть -точки с запятой только в конце строк, когда они находятся в конце каждого оператора INSERT:

$ awk 'BEGIN{RS=ORS=";\n"} {print} !(NR%2){print "commit"}' file
INSERT INTO X..... );
INSERT INTO X..... );
commit;
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
commit;
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
commit;
INSERT INTO X..... );

В противном случае, с любым awk в любой оболочке на каждом компьютере UNIX:

$ awk '/^INSERT/{ if (c++ == 2) {print "commit;"; c=1} } {print} END{if (c == 2) print "commit;"}' file
INSERT INTO X..... );
INSERT INTO X..... );
commit;
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
commit;
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
commit;
INSERT INTO X..... );

Вам нужен раздел END, так как он вставляется перед N+1-м оператором INSERT, а не после N-го оператора INSERT, и вам нужно обработать случай, когда во входных данных ровно кратно N INSERT, например.:

$ cat file
INSERT INTO X..... );
INSERT INTO X..... );
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
INSERT INTO X..... );
INSERT INTO X..... );

Без оператора END мы не сможем добавить окончательныйcommit;:

$ awk '/^INSERT/{ if (c++ == 2) { print "commit;"; c=1 } } {print}' file
INSERT INTO X..... );
INSERT INTO X..... );
commit;
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
commit;
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
commit;
INSERT INTO X..... );
INSERT INTO X..... );

пока с ним у нас получается:

$ awk '/^INSERT/{ if (c++ == 2) { print "commit;"; c=1 } } {print}; END{if (c == 2) print "commit;"}' file
INSERT INTO X..... );
INSERT INTO X..... );
commit;
INSERT INTO X.....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X..... );
commit;
INSERT INTO X..... );
INSERT INTO X.....foo
bar
foo bar);
commit;
INSERT INTO X..... );
INSERT INTO X..... );
commit;

и, конечно, если вы просто хотите commit;после последней INSERT, независимо от того, сколько их присутствует, просто удалите if ( c == 2 )из END и оставьте print.

0
28.04.2021, 23:21

Теги

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