linux - 用 awk 替换 sql 列

标签 linux bash awk

我在替换 SQL 脚本中的列时遇到问题。

我有这样的数据(test.sql):

INSERT INTO TABLE
  (ID,TEXT)
VALUES
 (1,'TEXT');

INSERT INTO TABLE
 (ID,TEXT)
VALUES
  (2,'TEXT242');

INSERT INTO TABLE
 (ID,TEXT)
VALUES
(3,'TEXT424242');

我想用新值替换 ID 列上的“TEXT”。没关系,我可以这样做:

NEW="NEW"
grep 3 test.sql | awk -F "," -v OFS=, '{$2'$index'="'"'${NEW}'"'"; print }'

它将打印:

(3,'NEW');

所以,我有两个问题:

  1. 我希望看到包括新行在内的所有行都像这样更改:

    INSERT INTO TABLE
      (ID,TEXT)
    VALUES
     (1,'TEXT');
    
    INSERT INTO TABLE
      (ID,TEXT)
    VALUES
      (2,'TEXT242');
    
    INSERT INTO TABLE
      (ID,TEXT)
    VALUES
      (3,'NEW');
    
  2. 我想要一个完全匹配:所以 3 只有 3 而不是 30 33...

最佳答案

如果您只需要解决这个特定问题(不需要完全解析语句并且格式没有变化),sed 可以提供更简单的解决方案:

更新:OP 已阐明它是第 8 列,其值应被替换。

# Specify ID to match and replacement text.
id=3 new="NEW"

# Let `sed` perform the substitution. 
# `sed` outputs ALL lines by default, whether a substitution took place or not.
sed -E \
  "s/\($id(,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+,[^,]+),[^,]+(.*)/($id\1,'$new'\2/" \
  test.sql

如您所见,,[^,]+(...) 中重复了 6 次,以捕获中间的列值 - 遗憾的是,使用 {6} 重复 6 次不是一个选项,因为那样只会捕获模式的最后实例。


一个基于字段的awk解决方案:

更新:OP 已阐明它是第 8 列,其值应被替换。

这种更灵活的解决方案还允许您传入目标列的从 1 开始的索引。但是,假定 ID 列总是第一个

awk -F '[,()]' -v id=3 -v ndx=8 -v new="'NEW'" '
  $2==id {
    $(ndx+1)=new # replace the column value
     # Row has been rebuilt with just spaces as separators
     # output it in the original format.
    printf " (%s", id
    for (i=3;i<NF;++i) printf ",%s", $i
    print ");"
    next 
  }
  { print }
  ' test.sql

请注意,不会保留确切的前导空格。

另请注意,由于输入行以字段分隔符(()开始awk 在开头创建了一个额外的空字段; 因此,索引增加 1。


重申一下警告:一般来说,awksed 都不是解析 SQL [DML] 语句的正确工具。

关于linux - 用 awk 替换 sql 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23111971/

相关文章:

csv - 如何使用 awk 将列插入到 CSV 文件中

linux - 如何在 bash 脚本中将字符串或变量作为 awk 的多个参数传递?

基于 Python Web 的解释器安全问题

linux - 如何使用 ruby​​ 脚本以 ROOT 用户身份登录 linux 终端

bash - 如何在远程机器上运行 SQL 查询并以 CSV 格式保存在本地

linux - 使用 bash one liner 创建别名

linux - 使用awk测量同一列中2个数字之间的差异

linux - 我们如何在 bash 中使用 for 循环将日期列表转换为 yyyymmdd 格式

c - x86 中 stat 结构的布局

linux - 我该如何杀死这个 bash 脚本?