removendo extensões em uma coluna

5

Eu tenho um arquivo como este

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402.5
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046.3
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838.1

Eu quero remover as extensões numéricas do final na terceira coluna para que meu arquivo de saída se pareça com isso

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

Como posso fazer isso na linha de comando usando preferencialmente awk ? Eu posso fazer isso em perl , mas tenho certeza que existe uma única linha de comando para fazer isso.

    
por user3138373 17.11.2014 / 19:24

5 respostas

6

Com o awk:

awk -F'.' '{print $1}' file

-F opção altera o separador de campo padrão (espaço) para ponto (.).
$1 é o índice de posição de campo (com. separador de campos).

{ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402}.{5}
                  ^^ field index is $1                                          ^^$2

Com rev e awk:

rev file | awk -F'.' '{print $2}'|rev # reverse characters of each lines,\
                                        print field number 2 with (.) separator \
                                        and reverse the result again

O utilitário rev copia os arquivos especificados para a saída padrão, revertendo a ordem dos caracteres em todas as linhas. Se nenhum arquivo for especificado, a entrada padrão será lida.

Com sed:

sed 's/.[0-9]*$//' file

sed 's/.[^.]*$//' file

$ ponto para o final da linha. Na primeira busca do comando sed por char (.), Seguido por zero ou mais ocorrências de números e substituí-los por espaços em branco.

No segundo comando sed, remova tudo o que é seguido por (.) e também remova o próprio ponto (.).

Com rev e sed:

rev file| sed 's/.*[.]//' |rev

Excluir tudo antes do ponto (.) Também inclua e remova. em si.

Com o grep:

grep -oP '.*(?=\.[0-9])' file
    -o, --only-matching
          Print only the matched (non-empty) parts of a matching line,
          with each such part on a separate output line.
    -P, --perl-regexp
          Interpret PATTERN as a Perl compatible regular expression (PCRE)

(?=pattern) : Lookahead positivo: o constructo lookahead positivo é um par de parênteses, com o parêntese de abertura seguido por um ponto de interrogação e um sinal de igual.

.*(?=\.[0-9]) : (lookahead positivo) corresponde a tudo ( .* ) seguido por um ponto (.) e a quaisquer ocorrências de números, sem tornar o padrão ( \.[0-9] ) parte da correspondência.

Com rev e grep:

rev file |grep -oP '(?<=[0-9]\.).*' |rev

rev file |grep -oP '[0-9]\.\K.*' |rev

(?<=pattern) : lookbehind positivo. Um par de parênteses, com o parêntese de abertura seguido por um ponto de interrogação, símbolo "menor que" e um sinal de igual.

(?<=[0-9]\.).* (lookbehind positivo) corresponde a tudo que é seguido por ocorrências de números e termina com ponto (.).

No segundo comando grep, você pode usar o nifty \K no lugar da asserção lookbehind.

Com corte:

cut -f1 -d. file

cut -c 1-77 file # Print first 77 characters of each line.
cut - remove sections from each line of files

-d, --delimiter=DELIM
      use DELIM instead of TAB for field delimiter

-f, --fields=LIST
      select  only  these  fields;

-c, --characters=LIST
      select only these characters

Com loop while:

while read line; do echo "${line::-2}";done <file

Isso funcionará se você tiver apenas um número com comprimento = 1 no final de cada linha e o tamanho da correção. comando acima remover último dois caracteres no final de todas as linhas no arquivo de entrada. comandos alternativos são ${line%??} .

    
por 17.11.2014 / 21:26
4

Supondo que as extensões sejam de todos os dígitos:

perl -pi -e 's/\.\d+$//' /path/to/file

-i faz a edição no local (como em sed ). \d significa dígitos e $ indica o fim da linha.

com awk :

awk 'gsub(/\.[0-9]+$/,"")' /path/to/file

gawk tem uma opção de edição no local em versões mais recentes, mas não tenho certeza de como isso é portátil. gsub suporta um parâmetro opcional, especificando a coluna de destino:

awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file

O último formulário tem o efeito colateral indesejado de separar cada coluna por um único espaço em sua saída, como se você tivesse feito print $1,..,$NF . Eu não sei porque.

    
por 17.11.2014 / 19:27
4

Usar awk é simples, basta definir seu separador de campo como . :

awk -F. '{print $1}' file

Outra abordagem, usando o shell (neste caso, bash):

while IFS=.; read -r lines _; do  line+=("$lines"); done <file                                                                           
printf "%s\n" "${line[@]}"
ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838
    
por 17.11.2014 / 21:26
3

Com sed , você pode fazer:

sed 's/\.[0-9][0-9]*$//' x.txt

Supondo que o nome do arquivo seja x.txt . Se você quiser modificar o arquivo in-line, use a opção -i de sed conforme abaixo:

sed -i 's/\.[0-9][0-9]*$//' x.txt

Se você deseja preservar o conteúdo do arquivo original, use o redirecionamento abaixo:

sed 's/\.[0-9][0-9]*$//' x.txt > newfile.txt
    
por 17.11.2014 / 19:27
1

Isso remove tudo começando com o ponto:

sed 's/\..*//'
    
por 17.11.2014 / 19:28