【问题标题】:Filtering Data in CSV file过滤 CSV 文件中的数据
【发布时间】:2019-08-03 05:30:57
【问题描述】:

我有这种格式的 CSV 文件

a,b,c,d,e,f,no disk detected
a,b,c,d,e,f,disk run into error
a,b,c,d,e,f,no memory in the server
a,b,c,d,e,f,memory has correctable errors

在最后一列,我需要搜索单词

磁盘并将其替换为磁盘错误 内存并将其替换为内存错误 那部分我已经弄清楚了

 cat filename.csv |awk -F "," '{print $NF}' |sed 's/^.*disk.*$/disk error/'  |sed 's/^.*memory.*$/memory error/' 

现在sed替换这个字符串时我需要帮助的部分,是否可以写入同一个文件(filename.csv)或生成一个包含所有列+更新列的新文件,所以新文件看起来像这样

 a,b,c,d,e,f,disk error
 a,b,c,d,e,f,disk error
 a,b,c,d,e,f,memory error
 a,b,c,d,e,f,memory error

【问题讨论】:

    标签: regex linux csv awk sed


    【解决方案1】:

    awk 解决方案:

    awk -F, '{if ($NF~/disk/) $NF="disk error"; if ($NF~/memory/) $NF="memory error";}1' OFS=, file
    

    使用 GNU awk v4.1.0+,您可以添加 -i inplace 开关来更改 file 就地。
    否则,请尝试awk .... file | tee file

    所以上面的命令本身不需要 GNU awk,但是如果你有 GNU awk,你可以用这种更简洁的方式来做:

    awk -F, '{match($NF,"(disk|memory)",m);$NF=m[1] " error";}1' OFS=, file
    

    NF 表示列号,$NF 表示最后一列。
    -F,FS 字段分隔符设置为逗号。
    OFS=, 将输出字段分隔符设置为逗号。

    【讨论】:

    • 我们可以不用最后一个分号。
    • @ClaesWikner 是的,可以保存。谢谢你提到它。我在这里添加它是为了有某种闭包,只是感觉更好:)
    【解决方案2】:

    使用sed 更容易:

    sed -E 's/^(.+,).*(disk|memory).*$/\1\2 error/' file.csv
    

    a,b,c,d,e,f,disk error
    a,b,c,d,e,f,disk error
    a,b,c,d,e,f,memory error
    a,b,c,d,e,f,memory error
    

    要在同一文件中进行内联更改,请使用:

    sed -i.bak -E 's/^(.+,).*(disk|memory).*$/\1\2 error/' file.csv
    

    == 详情 ==

    搜索正则表达式:

    • ^:开始
    • (.+,): 贪婪匹配直到最后一个逗号并在#1组中捕获它
    • .*(disk|memory):匹配diskmemory之前匹配0个或多个字符并在组#2中捕获它
    • .*$: 匹配结束前 0 个或多个字符

    替换模式:

    • \1: 反向引用组 #1 以将文本放置到最后一个逗号返回
    • \2 error:附加disk errormemory error

    【讨论】:

      猜你喜欢
      • 2014-12-30
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多