Como remover símbolos de uma coluna usando o awk

5

Eu tenho dados como este:

chr1    134901  139379  -   "ENSG00000237683.5";
chr1    860260  879955  +   "ENSG00000187634.6";
chr1    861264  866445  -   "ENSG00000268179.1";
chr1    879584  894689  -   "ENSG00000188976.6";
chr1    895967  901095  +   "ENSG00000187961.9";

Geramos analisando um arquivo GTF

Eu quero remover os " e ; da coluna 5 usando o awk ou o sed, se possível. O resultado seria assim:

chr1    134901  139379  -   ENSG00000237683.5
chr1    860260  879955  +   ENSG00000187634.6
chr1    861264  866445  -   ENSG00000268179.1
chr1    879584  894689  -   ENSG00000188976.6
chr1    895967  901095  +   ENSG00000187961.9
    
por System 14.01.2016 / 20:41

6 respostas

6

Usando gsub :

awk '{gsub(/\"|\;/,"")}1' file
chr1    134901  139379  -   ENSG00000237683.5
chr1    860260  879955  +   ENSG00000187634.6
chr1    861264  866445  -   ENSG00000268179.1
chr1    879584  894689  -   ENSG00000188976.6
chr1    895967  901095  +   ENSG00000187961.9

Se você quiser operar somente no quinto campo e preservar quaisquer citações ou ponto e vírgula em outros campos:

awk '{gsub(/\"|\;/,"",$5)}1' file 
    
por 14.01.2016 / 20:45
5

Usando o sed para remover todas as instâncias de '";': sed -i 's/[";]//g' file

Para remover apenas da quinta coluna, o sed provavelmente não é a melhor opção.

    
por 14.01.2016 / 20:54
5

Se os dados estiverem formatados exatamente como mostrado (ou seja, nenhum outro " ou ; em outras colunas que precisem ser preservados), você poderá simplesmente usar tr para remover esses caracteres:

tr -d '";' < input.txt > output.txt
    
por 15.01.2016 / 00:40
3

Eu sei que o post original pediu sed ou awk, mas se você quiser remover o "e; de apenas a quinta coluna eu usaria regex e php. Há provavelmente uma maneira de fazer isso no AWK, mas eu gosto de usar as ferramentas mais fáceis.

<?php

foreach(file($argv[1]) as $line){

    $matches = array();
    preg_match('/^(\w+)\s+(\d+)\s+(\d+)\s+(\-|\+)\s+"(\w+.\d)"\;/',$line,$matches);
    $matched_line = array_shift($matches); // remove the first element
    vprintf("%s\t%s\t%s\t%s\t%s\n",$matches);
}

isso produziria isso

$ php /tmp/preg_replace.php /tmp/data
chr1    134901  139379  -   ENSG00000237683.5
chr1    860260  879955  +   ENSG00000187634.6
chr1    861264  866445  -   ENSG00000268179.1
chr1    879584  894689  -   ENSG00000188976.6
chr1    895967  901095  +   ENSG00000187961.9
    
por 14.01.2016 / 21:08
3

Uma solução sed que garante que estamos apenas mexendo na quinta coluna:

sed -E 's/^(([^ ]+ +){4})"([^"]+)";$//' infile
chr1    134901  139379  -   ENSG00000237683.5
chr1    860260  879955  +   ENSG00000187634.6
chr1    861264  866445  -   ENSG00000268179.1
chr1    879584  894689  -   ENSG00000188976.6
chr1    895967  901095  +   ENSG00000187961.9

Isso funciona também sem ERE ( -E ou -r para alguns sed mais antigos), mas requer muito mais barras invertidas. O + -quantifier é somente ERE de acordo com a especificação POSIX 1 e pode ser substituído por {1,} (ou \{1,\} para BRE).

Caso as colunas não sejam separadas por espaços, os espaços podem ser substituídos pela classe de caracteres [:blank:] POSIX para também corresponder às guias.

O regex em detalhes:

^               # Anchored at start of line
(               # Capture group 1 for first 4 columns
    (           # Capture group 2 for repeat count
        [^ ]+   # 1 or more non-spaces
         +      # 1 or more spaces
    ){4}        # 4 times "word plus spaces" (columns)
)               # End capture group 1
"               # Column 5 starts with double quote (not captured)
(               # Capture group 3 for column 5
    [^"]+       # One or more non-quote characters
)               # End capture group 3
";              # Quote and semicolon at end of column 5
$               # Anchored at end of line

1 O GNU sed, como extensão, permite que \+ seja usado no BRE também.

    
por 17.01.2016 / 07:28
2

Se cada linha tiver um tamanho fixo (como no exemplo) que

cut -c1-28,30-46 INFILE

funcionará.

    
por 17.01.2016 / 08:13