【问题标题】:Search for a pattern in Column in a CSV and replace another pattern in the same line using sed command在 CSV 中的列中搜索模式并使用 sed 命令替换同一行中的另一个模式
【发布时间】:2015-06-14 05:38:24
【问题描述】:

我想检查 CSV 文件第二列中的模式(仅当模式以开头时),如果该模式存在,则替换同一行中的其他内容。

如果模式 676 存在于第二列中,我为跟随 csv 编写了以下 sed 命令以将 I 更改为 N。但它也会检查第 7 列和第 9 列中的 676,因为存在 ,676。理想情况下,如果前缀 676 存在,我只想检查第二行。我只想检查第二列中前缀的 676(模式不在第二个值 Ex-46769777 的中间或末尾),然后将 ,I, 更改为 ,N,。

sed -i  '/,676/ {; s/,I,/,N,/;}' temp.csc

6768880,55999777,S,I,TTTT,I,67677,yy
6768880,676999777,S,I,TTTT,I,67677,yy 
6768880,46769777,S,I,TTTT,I,67677,yy  

需要预期的结果

6768880,55999777,S,I,TTTT,I,67677,yy
6768880,676999777,S,N,TTTT,N,67677,yy
6768880,40999777,S,I,TTTT,I,67677,yy  

【问题讨论】:

  • 很难在sed 中编写可以做到这一点的可支持代码。你真的在乎它是不是sedawk 的设计考虑到了这些问题,并且很容易实现。祝你好运。
  • 您的输出中有错误。 46769777怎么变成40999777

标签: linux shell sed command


【解决方案1】:

如果您不受sed 的约束,awk 可能是您更好的选择。试试这个:

awk -F"," '{match($2,/^676/)&&gsub(",I",",N")}{print}' temp.csc

match 语法将第二列与以 (^) 676 开头的数字匹配。gsubI 替换为 N

结果: 6768880,55999777,S,I,TTTT,I,67677,yy 6768880,676999777,S,N,TTTT,N,67677,yy 6768880,46769777,S,I,TTTT,I,67677,yy

【讨论】:

  • 可以缩短为:awk -F, '{match($2,/^676/)&&gsub(",I",",N")}1'
  • 可以进一步缩短:awk -F, '$2~/^676/{gsub(",I",",N")}1'
【解决方案2】:

这要求在进行任何更改之前676 出现在第二列的开头:

$ sed   '/^[^,]*,676/ s/,I,/,N,/g' file
6768880,55999777,S,I,TTTT,I,67677,yy
6768880,676999777,S,N,TTTT,N,67677,yy 
6768880,46769777,S,I,TTTT,I,67677,yy  

注意事项:

  • 正则表达式/^[^,]*,676/ 要求676 出现在第一次出现逗号之后。更详细:

    • ^ 匹配行首

    • [^,]* 匹配第一列

    • ,676 匹配第一个逗号,后跟676

  • 在您想要的输出中,,I, 每次出现在行上时都被替换为 ,N,。为此,g(意思是全局)被添加到了替换命令中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 2021-04-02
    • 1970-01-01
    • 2018-10-28
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多