如何使用 sed 编辑 CSV 文件?

如何使用 sed 编辑 CSV 文件?

我有一个这样的 CSV 文件:

hostname1 | role1 | environment | tag,list | |
hostname2 | role2 | environment | tag,list,longer | |
hostname3 | role3 | environment | | |

我需要一个sed表达式,如果之前没有标签,则向带有标签的列(4列)添加一个新标签,如果已经存在标签,则插入一个带有逗号的新标签。我试过这个:

sed "s/\(^$server |.*|.*|\) \(.*|.*|$\)/\1 new,\2/" testfile.csv

其中服务器在外部定义如下:

server="hostname2"

但它不起作用,并且如果标签列表为空,它就不会处理逗号。

您如何使用 sed 来实现这一点?

答案1

发现正则表达式时常见的错误是认为它们可以用作解析器(因此您会看到诸如“如何使用 REGEX 解析 XML 文件?”之类的问题)。但是,您不能在正则表达式中插入太多逻辑:对于像您这样的复杂问题,您要么需要一个解析器,要么需要一个以上的正则表达式。

如果要使用正则表达式,则需要两个:一个用于非空标签情况,一个用于空标签字段。这两个正则表达式可能如下所示:

s/^(hostname123 \|.*?\|.*?\|\s*)(\S+\s*\|.*?\|)$/\1new,\2/
s/^(hostname123 ?\|.*?\|.*?\|)\s*(\|.*?\|)$/\1 new \2/

这两个表达式可以通过管道一起使用sed

sed 'expression1' | sed 'expression2'

或者更好的是,使用以下命令:

sed -r -e '/^'"$server"' \|/ { s/^(.*?\|.*?\|.*?\|\s*)(\S+\s*\|.*?\|)$/\1new,\2/; s/^(.*?\|.*?\|.*?\|)\s*(\|.*?\|)$/\1 new \2/ }' testfile.csv

这比使用两个更有效,sed因为它不需要解析文件两次。

相关内容