Truncar a terceira coluna até que as strings dadas

2

ENTRADA:

W41784094   CH60104475  lasbalsrbla bla foo bar bla PT~CH60104475
W41788464   WO60444453  hellobla bla -bla foo bar 432 alaf. PT~CH60107925
W41753387   IN61026681  sim##bla-bla bla foo bar blab lba la:bla32 bla

OUTPUT:

W41784094   CH60104455  CH60104455
W41788464   WO60444453  CH60107925
W41753387   IN61026681  NA

Pergunta : Como posso truncar a terceira coluna até "PT ~"?

Mas se nem sempre houver um "PT ~", será necessário um "NA": \

Tab é o separador.

    
por LoukiosValentine79 02.07.2015 / 21:35

2 respostas

4

Isso é feito com mais facilidade usando awk no lugar de sed ; no caso de awk ser uma opção:

< input awk 'BEGIN {FS=OFS="\t"} {if ($3~/PT~/) sub(/.*PT~/, "", $3); else $3="NA"; print}'

Expandido:

BEGIN {
    FS=OFS="\t"
}
{
    if ($3 ~ /PT~/)
        sub(/.*PT~/, "", $3);
    else
        $3 = "NA";
    print
}
  • BEGIN {FS=OFS="\t"} : configura o separador de campos 1 e o separador de campos de saída 2 como TAB , de modo que cada string TAB -separated é destinada como um campo de um registro ( 1 ) e para que o separador seja impresso após cada registro ( 2 );
  • {if ($3~/PT~/) sub(/.*PT~/, "", $3); else $3="NA"; print} : se o terceiro campo do registro ( $3 ) corresponder ( ~ ) à expressão regular PT~ ( /PT~/ ) (ou seja, se contiver), substitua a primeira correspondência mais ampla à esquerda ( sub() ) da expressão regular /.*PT~/ ( /.*PT~/ , que corresponde a tudo até a última ocorrência de uma substring PT~ ) com uma string vazia ( "" ) no terceiro campo do registro ( $3 ), caso contrário, defina o terceiro campo ( $3 ) como NA ( "NA" ) e imprima o registro;
por 02.07.2015 / 21:55
2
sed -e's/\(\t.*\t\).* PT~//;t' \
    -e's/\t[^\t]*/\tNA/2'        

Isso deve funcionar para você, embora ele só pare de remover os caracteres na última ocorrência de PT no último campo da linha.

Além disso, dependendo da sua versão sed , talvez você tenha que usar literalmente < tab > caracteres em todos os lugares eu uso o escape \t .

A essência é procurar por duas guias em uma linha separada por qualquer quantidade de caracteres e, se elas forem, em algum momento, seguidas pela string <space>PT~ , então s/// ubstitute away all, mas o st \( capturou o subgrupo \) do / endereçado / pattern-space. Para ser justo, isso depende de um limite de três campos, mas a primeira declaração de substituição pode ser alterada para:

sed -e's/^\(\([^\t]*\t\)\{2\}\)[^\t]* PT~//;t' ...

... portably, ou, com GNU ou BSD sed ...

sed -Ee's/^(([^\t]*\t){2})[^\t]* PT~//;t' ...

... para limitar definitivamente a declaração s/// ubstitution apenas aos primeiros 3 campos.

Em qualquer caso, o t est se afasta se a substituição anterior for bem-sucedida e, assim, a próxima s/// ubstitution substituirá o campo delimitado pela terceira guia por uma linha que não corresponda à <space>PT~ string com apenas a string NA .

sed -e's/\(\t.*\t\).* PT~//;t'  \
    -e's/\t[^\t]*/\tNA/2'       <<\IN
W41784094       CH60104475      lasbalsrbla bla foo bar bla PT~CH60104475
W41788464       WO60444453      hellobla bla -bla foo bar 432 alaf. PT~CH60107925
W41753387       IN61026681      sim##bla-bla bla foo bar blab lba la:bla32 bla
IN
W41784094       CH60104475      CH60104475
W41788464       WO60444453      CH60107925
W41753387       IN61026681      NA
    
por 02.07.2015 / 22:12