Поскольку все классные ответы на awk уже были приняты, я начал играть с PCRE lookaround, поэтому, если вы можете использовать perl, вот что для этого:
perl -p -e 's/(?<=(\|)|(;))[^I][^P][^L][^;\n]*(;|(\n))|/\4/g if $.>1;s/;$//' file
COL1|COL2
CRIC1|IPL_M1;IPL_M2
CRIC2|IPL_M3
CRIC3|
CRIC4|IPL_M5;IPL_M
CRIC5|
Редактировать: Тестирование немного с более чем 3 строки (FO
):
$ cat foo
COL1|COL2
CRIC1|IPL_M1;IPL_M2;TEST_M1;FO;FO
CRIC2|ODI_M1;IPL_M3;FO;FO
CRIC3|FO;ODI_M3;TEST_M5
CRIC4|FO;IPL_M5;FO;ODI_M5;IPL_M;RANGI_M1
CRIC5|FO;RANGI_M1
вывод
COL1|COL2
CRIC1|IPL_M1;IPL_M2
CRIC2|IPL_M3
CRIC3|
CRIC4|IPL_M # fails if <3 preceeds a match
CRIC5|
Так что да, это не удается.Кажется, это работает немного лучше (изменено на: [^I;\n][^P;\n]?[^L;\n]?
):
$ perl -p -e 's/(?<=(\|)|(;))[^I;\n][^P;\n]?[^L;\n]?[^;\n]*(;|(\n))|/\4/g
if $.>1;
s/;$//' foo
$ awk '
BEGIN{ FS=OFS="|" }
{
n=split($2,a,";")
for(i=1;i<=n;i++)
if(a[i]~/^IPL/||NR==1)
b=b (b==""?"":";") a[i]
print $1,b;b=""
}' file
выходы:
COL1|COL2
CRIC1|IPL_M1;IPL_M2
CRIC2|IPL_M3
CRIC3|
CRIC4|IPL_M5;IPL_M
CRIC5|