如何使用unix shell脚本在条件中添加左括号和右括号

时间:2018-11-15 16:34:17

标签: shell unix sed

我的文件中有条件,大约有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 :(得分:4)

这就是您要寻找的

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使匹配的字符不区分大小写。

答案 1 :(得分:2)

让我们逐步进行。

我猜最好的规则是:

  • IN(不区分大小写)IN
  • 其后是:一个数字[0-9]\+
  • 可选地后跟多个(*):逗号和数字,[0-9]

这将导致正则表达式: IN[0-9]\+\(,[0-9]\+\)*

下一步是添加强制(\s)和可选(\s*)空格:

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

现在将\sIN\s*的{​​{1}}替换为[0-9]\+\s*\(,\s*[0-9]\+\s*\)*,则需要捕获组。

\1(\2)

现在正则表达式必须放在\(\sIN\s*\)\([0-9]\+\s*\(,\s*[0-9]\+\s*\)*\) 内(s//\1(\2)/i表示不区分大小写)

i

最后,我们有了一个shell命令,其中包括发生错误时的备份。

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