как добавить открывающие и закрывающие скобки в условии, используя скрипт оболочки Unix - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть условия в файле, который имеет около 10 тысяч строк. Как показано ниже.

COLUMN_NAME NOT IN 1234534
COLUMN_NAME1  NOT  IN  34252
COLUMN_NAME_2 not in    67496575
COLUMN_NAME NOT in   1234534
foo COLUMN_NAME NOT IN (1234534,453535) rest of the line
COLUMN_NAME NOT IN 1234534,453535
columnsd not in (23123124232,6464777) rest on the line
COLUMN_NAME NOT IN 1234534
COLUMN_NAME  NOT  IN  1234534
fdfsdf COLUMN_NAME not in 1234534
COLUMN_NAME not in   1234534
column NOT IN (6764577,434545)
COLUMN_NAME not in   (1234534)

Я хочу использовать команду sed для добавления скобок после предложения IN. Я хочу заменить приведенные выше условия на результат, как показано ниже.

COLUMN_NAME NOT IN (1234534)
COLUMN_NAME1  NOT  IN  (3422)
COLUMN_NAME_2 not in    (67496575)
COLUMN_NAME NOT in   (1234534)
COLUMN_NAME NOT IN (1234534,453535) rest of the line
COLUMN_NAME NOT IN (1234534,453535)
columnsd not in (23123124232,6464777) rest on the line
COLUMN_NAME NOT IN (1234534)
COLUMN_NAME  NOT  IN  (1234534)
fdfsdf COLUMN_NAME not in (1234534)
COLUMN_NAME not in   (1234534)
column NOT IN (6764577,434545)
COLUMN_NAME not in   (1234534)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Давайте рассмотрим шаг за шагом.

Полагаю, лучшим правилом будет:

  • IN (без учета регистра) IN
  • , за которым следует:число [0-9]\+
  • , за которым может следовать несколько символов (*): запятая и число ,[0-9]

Это приведет к регулярному выражению: IN[0-9]\+\(,[0-9]\+\)*

Следующим шагом является добавление обязательных (\s) и необязательных (\s*) пробелов:

\sIN\s*[0-9]\+\s*\(,\s*[0-9]\+\s*\)*

Теперь для замены \sIN\s* [0-9]\+\s*\(,\s*[0-9]\+\s*\)* на \1(\2) вам нужны группы захвата.

\(\sIN\s*\)\([0-9]\+\s*\(,\s*[0-9]\+\s*\)*\)

Теперь регулярное выражение должно идти внутрь s//\1(\2)/i (i означает регистр не учитывается)

s/\(\sIN\s*\)\([0-9]\+\s*\(,\s*[0-9]\+\s*\)*\)/\1(\2)/i

И, наконец, у нас есть команда оболочки, включая резервную копию вслучай ошибок.

sed -i.bak 's/\(\sIN\s*\)\([0-9]\+\s*\(,\s*[0-9]\+\s*\)*\)/\1(\2)/i' filename

Я проверил это на данных вашего примера и вывел:

COLUMN_NAME NOT IN (1234534)
COLUMN_NAME1  NOT  IN  (34252)
COLUMN_NAME_2 not in    (67496575)
COLUMN_NAME NOT in   (1234534)
foo COLUMN_NAME NOT IN (1234534,453535) rest of the line
COLUMN_NAME NOT IN (1234534,453535)
columnsd not in (23123124232,6464777) rest on the line
COLUMN_NAME NOT IN (1234534)
COLUMN_NAME  NOT  IN  (1234534)
fdfsdf COLUMN_NAME not in (1234534)
COLUMN_NAME not in   (1234534)
column NOT IN (6764577,434545)
COLUMN_NAME not in   (1234534)
0 голосов
/ 15 ноября 2018

Это будет то, что вы ищете

sed -i .bak 's/\(\sin\s\+\)\([^() ]\+\)/\1(\2)/i' file

Объяснение

s/regexp/replacement/flags пытается сопоставить строку ввода с regexp и, если это удается, заменяет соответствующую часть на replacement.

  1. regexp часть:

    • \(\sin\s\+\) (ERE: (\sin\s+)) соответствует пробелу, за которым следует in плюс один или несколько пробелов, и сохраняет сопоставленную часть в группе захвата 1,
    • \([^() ]\+\) (ERE: ([^() ]+)) сопоставляет группу непробельных символов без скобок и сохраняет ее в группе захвата 2,
  2. replacement часть:

    • \1(\2) расширяется до <capture group 1>(<capture group 2>),
  3. flags часть:

    • i делает сопоставление без учета регистра.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...