Выборочный поиск и замена определенных строк с помощью регулярного выражения - PullRequest
3 голосов
/ 27 мая 2010

У меня есть файл, содержащий много операторов SQL, таких как:

CREATE TABLE "USER" (
    "ID" INTEGER PRIMARY KEY,
    "NAME" CHARACTER VARYING(50) NOT NULL,
    "AGE" INTEGER NOT NULL
);

COPY "USER" (id, name, age) FROM stdin;
1   Skywalker   19
2   Kenobi      57

Я хочу, чтобы имена столбцов в операторах COPY были в верхнем регистре и заключены в кавычки:

COPY "USER" ("ID", "NAME", "AGE") FROM stdin;

Используя sed, я нашел следующее регулярное выражение:

sed -r 's/([( ])(\w+)([,)])/\1"\U\2\E"\3/g'

Он заменяет имена столбцов, но он недостаточно избирателен и заменяет другие слова в файле:

~/test]$sed -r 's/([( ])(\w+)([,)])/\1"\U\2\E"\3/g' star_wars_example
CREATE TABLE "USER" (
  "ID" INTEGER PRIMARY "KEY",
  "NAME" CHARACTER VARYING("50")NOT "NULL",
  "AGE" INTEGER NOT NULL
);

COPY "USER" ("ID", "NAME", "AGE") FROM stdin;
1   Skywalker   19
2   Kenobi      57

Чтобы избежать этой проблемы, я хочу, чтобы sed применил мое регулярное выражение только к строкам, начинающимся с COPY и заканчивающимся FROM stdin;.

Я посмотрел в lookahead / lookbehind, но они не поддерживаются в sed. Похоже, они поддерживаются в super-sed, но в настоящее время я использую Cygwin (Windows здесь обязательна ...), и он не доступен в списке пакетов.

Есть ли способ заставить sed рассматривать только конкретную строку?

Я подумал о том, чтобы пропустить мой файл через grep перед применением sed , но другие строки затем исчезнут с вывода.

Я что-то упускаю из виду?

Было бы замечательно, если бы ответ был легко применим при установке Cygwin по умолчанию. Я думаю, я мог бы попробовать установить Super-Sed на Cygwin, но я хотел бы знать, есть ли более очевидные идеи

1 Ответ

2 голосов
/ 27 мая 2010

Поскольку у меня нет доступного мне sed на данный момент, и я никогда не использовал группировку, эта команда может работать, а может и не работать (вообще, или по назначению) =)

Попробуйте

sed -r '/^COPY /{ s/([( ])(\w+)([,)])/\1"\U\2\E"\3/g }'

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

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

...