например:
CREATE TABLE MWWDATA."VTCat02" (
"ID" NUMBER(10) DEFAULT NULL ,
"Cat" VARCHAR2(255) DEFAULT NULL ,
"Style_Code" VARCHAR2(255) DEFAULT NULL ,
"Vendor_Style_#" VARCHAR2(255) DEFAULT NULL );
В приведенном выше примере я хочу вывести строку, которая начинается с CREATE TABLE, а в оставшейся строке вывести только первое поле.
Я хочу вывод как
CREATE TABLE MWWDATA."VTCat02" ("ID","Cat","Style_code","Vendor_Style_#");
решение1
С awk
:
awk '/^CREATE TABLE/{
inside = 1
sep = ""
printf "%s", $0
next
}
inside {
printf "%s", sep $1
sep = ","
if (/\);$/) {
print ");"
inside = 0
}
}'
В этом случае операторы начинаются с CREATE TABLE
в начале строки и заканчиваются на );
в конце строки (хотя и не в той же строке), а имя каждого столбца является первым полем последующих строк (то есть имена столбцов не могут содержать пробелы).
решение2
Больше похоже на работу для perl
:
perl -0777 -pe 's{(CREATE TABLE \S+\s+)\K(\((?:(?2)|.)*?\))}
{"(" . join(",", $2 =~ /".*?"/g) . ")"}gse'
(Предполагается, что заключенные в кавычки строки не содержат непарных скобок и имеют достаточно свежую версию perl
).
Разбито:
-0777
, установите разделитель записей на 0777 (невозможное значение байта), поэтому фактически включаетсячавкатьрежим, в которомperl
действует на весь вход в целом.-pe 'code'
:sed
режим. (еоценивает кодеxpression по одной записи за раз ип(после этого печатает).s{...}{...}gse
: заменятьгглобально, обрабатывает строку каксодна строка (.
также соответствует символам новой строки), и замена должна рассматриваться как perlевыражение дляеоценить.\K
: маркs начало части, подлежащей замене.(?2)
: один из способов сделать рекурсивное регулярное выражение. Здесь включено регулярное выражение, заключенное во вторую(...)
группу. Так\((:(?2)|.)*?\)
. Это a,(
за которым следует последовательность из большего количества(...)
групп или других символов (как можно меньше), за которыми следует)
.join(",", $2 =~ /".*?"/g)
объединяет список совпадающих строк".*?"
(то есть строк в кавычках)$2
запятой.
решение3
С использованием awk
:
awk '{if (NR==1) {printf "%s", $0} else {printf "%s,",$1}} END {printf "^H);\n"}' /tmp/inputfile
Первое совпадение, если мы находимся на первой строке ввода, если это так, вывести всю строку, в противном случае вывести первое слово, за которым следует запятая.
В качестве последнего шага напечатайте возврат на одну позицию, чтобы избавиться от последней запятой, и напечатайте закрывающую скобку и новую строку. Символ возврата на одну позицию вставляется в командную строку с помощью ctrl+vctrl+h. ctrl+hКлавиша соответствует 8-й букве алфавита (H), а код клавиши 8 соответствует возврату на одну позицию.
Результат будет следующим:
CREATE TABLE MWWDATA."VTCat02" ("ID","Cat","Style_Code","Vendor_Style_#");