Regex & Sed: Как подавить первую и вторую запятую в строке, содержащей ровно 9 запятых? - PullRequest
0 голосов
/ 14 января 2019

Я хотел бы подавить две первые запятые в строке, содержащей 10 и только 10 запятых (11 полей). Я не хочу стирать запятые в строке с 9 запятыми.

Я пробовал это:

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

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Я предполагаю, что вы используете 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 я заменил на space, так как Leon.ing,rombah без пробела внутри, простая полоска , станет 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 полей, разделенных запятыми.

0 голосов
/ 14 января 2019

Это может сработать для вас (GNU sed):

sed 's/,/&/9;T;s//&/10;t;s///;s///' file

Если нет по крайней мере 9 ,, оставьте строку как есть. Если есть 10 или более ,, оставьте строку как есть. В противном случае удалите первые 2 ,.

Альтернатива:

sed -r 's/^([^,]*),([^,]*),(([^,]*,){7}[^,]*)$/\1\2\3/' file
0 голосов
/ 14 января 2019

Вы можете использовать

sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*){7})$/\1\2\3\4/'

Детали

  • ^ - начало строки
  • ([^,]*) - Группа 1 (\1): любые 0+ символов, кроме ,
  • ,([^,]*) - , и группа 2 (\2), соответствующие любым 0+ символам, кроме ,
  • ,([^,]*) - , и группа 3 (\3), соответствующие любым 0+ символам, кроме ,
  • ((,[^,]*){7}) - семь вхождений ,, за которыми следуют 0+ символов, кроме ,
  • $ - конец строки.

См. онлайн sed демо :

s="Leonarfdsdy Dandfiel, Ingendfdfdfieur - Leon.inrombach, Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR"
sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*){7})$/\1\2\3\4/' <<< "$s"
# => Leonarfdsdy Dandfiel Ingendfdfdfieur - Leon.inrombach Hinderusen, 485,47580,SANKT VITH,BELGIQUE,0442345,2058560,FR
...