Regex&;Sed:如何在正好包含9个逗号的字符串中抑制第一个和第二个逗号?
我想在一个包含10个且仅包含10个逗号(11个字段)的字符串中抑制前两个逗号。我不想删除9个逗号行中的逗号 我试过这个:Regex&;Sed:如何在正好包含9个逗号的字符串中抑制第一个和第二个逗号?,regex,awk,sed,replace,terminal,Regex,Awk,Sed,Replace,Terminal,我想在一个包含10个且仅包含10个逗号(11个字段)的字符串中抑制前两个逗号。我不想删除9个逗号行中的逗号 我试过这个: sed '/^\([^,]*,\)\{10\}[^,]*$/s/,//1;s/,//2' 但它删除逗号,即使在包含少于10个逗号的句子中,它也会删除第一个和第三个逗号 例如: DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGIË,06346641,0636641,NL Leonarfdsdy Dandfiel, Ingendfdfdf
sed '/^\([^,]*,\)\{10\}[^,]*$/s/,//1;s/,//2'
但它删除逗号,即使在包含少于10个逗号的句子中,它也会删除第一个和第三个逗号
例如:
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGIË,06346641,0636641,NL
Leonarfdsdy Dandfiel, Ingendfdfdfieur - Leon.ing,rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
预期结果:
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGIË,06346641,0636641,NL
Leonarfdsdy Dandfiel Ingendfdfdfieur - Leon.ing rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
你可以用
sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*){7})$/\1\2\3\4/'
详细信息
-行的开头^
-第1组(([^,]*)
):除\1
以外的任何0+字符,
-,([^,]*)
和组2(,
)匹配除\2
以外的任何0+字符,
-,([^,]*)
和组3(,
)匹配除\3
以外的任何0+字符,
-出现七次((,[^,]*){7}
,后跟除,
以外的任何0+字符,
-字符串结束$
s=“Leonarfdsdy Dandfiel,Ingendfeur-Leon.inrombach,Hinderusen,48547580,比利时圣维思,04423452058560,法国”
sed-E的/^([^,]*),([^,]*),([^,]*)(,[^,]*)(,[^,]*){7})$/\1\2\3\4/'您可以使用
sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*){7})$/\1\2\3\4/'
详细信息
^
-行的开头
([^,]*)
-第1组(\1
):除,
以外的任何0+字符
,([^,]*)
-,
和组2(\2
)匹配除,
以外的任何0+字符
,([^,]*)
-,
和组3(\3
)匹配除,
以外的任何0+字符
((,[^,]*){7}
-出现七次,
,后跟除,
以外的任何0+字符
$
-字符串结束
见:
s=“Leonarfdsdy Dandfiel,Ingendfeur-Leon.inrombach,Hinderusen,48547580,比利时圣维思,04423452058560,法国”
sed-E的/^([^,]*),([^,]*),([^,]*)(,[^,]*)(,[^,]*){7})$/\1\2\3\4/'我猜您正在使用MacOS sed/BSD sed,请尝试以下操作:
sed -e '/^\([^,]*,\)\{10\}[^,]*$/s/,//; tLB' -e 'b' -e ':LB' -e 's/,/ /'
我使用了--posix
进行模拟,但不确定它是否能在您的操作系统上工作:
$ cat file
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGI?,06346641,0636641,NL
Leonarfdsdy Dandfiel, Ingendfdfdfieur - Leon.ing,rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
$ sed --posix -e '/^\([^,]*,\)\{10\}[^,]*$/s/,//; tLB' -e 'b' -e ':LB' -e 's/,/ /' file
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGI?,06346641,0636641,NL
Leonarfdsdy Dandfiel Ingendfdfdfieur - Leon.ing rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
请注意,第二个s
命令,我改为替换为空格
,因为Leon.ing,rombah
里面没有空格,simpy strip,
将变成Leon.ingrombach
这也可能奏效:
sed -e '/^\([^,]*,\)\{10\}[^,]*$/{' -e 's/,/ /' -e 's/,/ /}'
顺便说一句,我认为现在是您开始使用GNU sed的时候了:
brew install gnu-sed
ln -s /usr/local/bin/gsed /usr/local/bin/sed
此问题也更易于使用awk
:
awk -F, 'NF==11{sub(",","");sub(","," ")}1' file
仅当有11个逗号分隔的字段时才替换。我猜您使用的是MacOS sed/BSD sed,请尝试以下操作:
sed -e '/^\([^,]*,\)\{10\}[^,]*$/s/,//; tLB' -e 'b' -e ':LB' -e 's/,/ /'
我使用了--posix
进行模拟,但不确定它是否能在您的操作系统上工作:
$ cat file
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGI?,06346641,0636641,NL
Leonarfdsdy Dandfiel, Ingendfdfdfieur - Leon.ing,rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
$ sed --posix -e '/^\([^,]*,\)\{10\}[^,]*$/s/,//; tLB' -e 'b' -e ':LB' -e 's/,/ /' file
DE, LAEIES,Vlzgstraat, 16,2260,NIJLEN,BELGI?,06346641,0636641,NL
Leonarfdsdy Dandfiel Ingendfdfdfieur - Leon.ing rombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
请注意,第二个s
命令,我改为替换为空格
,因为Leon.ing,rombah
里面没有空格,simpy strip,
将变成Leon.ingrombach
这也可能奏效:
sed -e '/^\([^,]*,\)\{10\}[^,]*$/{' -e 's/,/ /' -e 's/,/ /}'
顺便说一句,我认为现在是您开始使用GNU sed的时候了:
brew install gnu-sed
ln -s /usr/local/bin/gsed /usr/local/bin/sed
此问题也更易于使用awk
:
awk -F, 'NF==11{sub(",","");sub(","," ")}1' file
仅当有11个逗号分隔的字段时才替换。这可能适用于您(GNU-sed):
如果没有至少9个,
的行保持原样。如果有10个或更多的,
的行保持不变。否则,移除前2个,
另一种选择:
sed -r 's/^([^,]*),([^,]*),(([^,]*,){7}[^,]*)$/\1\2\3/' file
这可能适用于您(GNU-sed):
如果没有至少9个,
的行保持原样。如果有10个或更多的,
的行保持不变。否则,移除前2个,
另一种选择:
sed -r 's/^([^,]*),([^,]*),(([^,]*,){7}[^,]*)$/\1\2\3/' file
请将示例输入和该示例输入的所需输出添加到您的问题中。您需要再次将正则表达式中的2
替换为1
;您已经在前面的替换中删除了第一个逗号,因此现在需要删除当前的第一个逗号。或者颠倒s/,//1
和s/,//2
命令的顺序。如果您想让这两个替换与您的条件模式保持一致,还必须将这两个替换放在花括号之间。您的示例只有九个逗号。@Cyrus您是对的,我更正了问题请将示例输入和该示例输入的所需输出添加到问题中。您需要再次将正则表达式中的2
替换为1
;您已经在前面的替换中删除了第一个逗号,因此现在需要删除当前的第一个逗号。或者颠倒s/,//1
和s/,//2
命令的顺序。如果你想让这两个替换与你的条件模式保持一致,你还必须把这两个替换放在花括号之间。你的例子只有九个逗号。@Cyrus你是对的,我纠正了这个问题,我试过了,但它似乎没有删除逗号@ΩlostA共享您尝试过的代码。另外,sed
和操作系统版本详细信息也会有所帮助。我试过了,但它似乎没有删除逗号@ΩlostA共享您尝试过的代码。另外,sed
和操作系统版本详细信息也会有所帮助。在你的提问脚本中:}
之后的1
做什么?@cars10m它表示真
,当没有给出块时,暗示{print$0}
。所以它基本上等于“True”{print$0}
注意,在awk
中没有明确的true
或false
boolen。啊,我最终得到了它:1
的行为就像一个“始终为真”的条件,并且,由于后面没有任何其他内容,awk的默认命令{print}
已应用。在ask脚本中:}
之后的1
做什么?@cars10m它表示true
,当没有给出块时,暗示{print$0}
。所以它基本上等于“True”{print