我只想从此 csv 中删除分组逗号以将变量数量更改为两个

我只想从此 csv 中删除分组逗号以将变量数量更改为两个

我有一个 csv,其中前几行如下所示

c("4288", "57534"),MIB1
c("2272", "2385"),FHIT
c("5550", "10531", "56239"),PREP
c("25809", "23669"),TTLL1

我想操纵变量的数量,以便括号中分组的所有内容都是一个变量。不幸的是,我的文档有多个条目,例如第 3 行,其中有多个逗号分隔括号内的值。

是否有一个 sed 表达式只能操作括号内的逗号?

预期的输出将是这样的:

c("4288" "57534"), MIB1
c("2272" "2385"),FHIT
c("5550" "10531" "56239"),PREP
c("25809" "23669"),TTLL1

干杯。

答案1

使用perlnot 来sed获得更高级的正则表达式:

perl -pe 's/(?:\G[^,)]*|\([^,)]*)\K,(?=.*?\))//g' input.csv
c("4288" "57534"),MIB1
c("2272" "2385"),FHIT
c("5550" "10531" "56239"),PREP
c("25809" "23669"),TTLL1

这将删除括号内出现的所有逗号。

答案2

我已经回答过相同的解决方案这里,这也适用于您的问题,此处稍作修改:

sed -E ':loop s/(\([^)]*),([^)]*\))/\1\2/; t loop' infile

分解:

笔记:未转义()外部字符类[...]用于分组匹配;字符类中转义的\(or或将会匹配文字和;是否定匹配,因此匹配“\)[...]()^[^)]任何单个字符,但不是)”。

那么我们有:

(\([^)]*):第一组比赛,\1指的是后面的裁判。
,: 匹配单个逗号。
([^)]*\)):第二组比赛,回溯\2指的是。

考虑如下所示的一个示例行并解释该匹配的工作原理:

c(("4288", "57534", "somtoher")),d("f1", "f2", "f3"),MIB1

(\([^)]*),([^)]*\))将匹配:

  1. 从第一个左括号(后跟除 a 以外的任何内容,)一直,到最后一个右括号);因此,第一组比赛\1将匹配(("4288", "57534",上面示例行的部分内容;

  2. 那么从最后一个,到第一个右括号之后到第一个右括号及其)本身都将在第二组比赛中\2;它将成为"somtoher")上面示例行的一部分。

  3. 在 的替换部分中\1\2,我们将两个匹配的组恢复回来,但在它们之间删除了逗号。

  4. :loop s///; t loop;执行步骤 1 到 3,直到在 sed 循环中清除(&之间的所有逗号(用作标签)。)loop

    第一次尝试时,我们的示例行将更改为:

    c(("4288", "57534" "somtoher")),d("f1", "f2", "f3"),MIB1
    

    第二次尝试将是:

    c(("4288" "57534" "somtoher")),d("f1", "f2", "f3"),MIB1
    

    第三次尝试将是:

    c(("4288" "57534" "somtoher")),d("f1", "f2" "f3"),MIB1
    

    等等。

相关内容