
Eu tenho um arquivo como este
ILMN_1343291 TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG NM_001402.5
ILMN_1343295 CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG NM_002046.3
ILMN_1651209 TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC NM_182838.1
Quero remover as extensões numéricas do final da terceira coluna para que meu arquivo de saída fique assim
ILMN_1343291 TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG NM_001402
ILMN_1343295 CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG NM_002046
ILMN_1651209 TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC NM_182838
Como posso fazer isso na linha de comando, de preferência usando awk
? Posso fazer isso, perl
mas tenho certeza de que existe uma única linha de comando para fazer isso.
Responder1
Com awk:
awk -F'.' '{print $1}' file
-F
opção alterar o separador de campo padrão (espaço) para ponto (.).
$1
é o índice da posição do campo (com . separador de campo).
{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 rev
utilitário copia os arquivos especificados para a saída padrão, invertendo a ordem dos caracteres em cada linha. Se nenhum arquivo for especificado, a entrada padrão será lida.
Com sed:
sed 's/.[0-9]*$//' file
sed 's/.[^.]*$//' file
$
apontar para o fim da linha. No primeiro comando sed, pesquise char(.) seguido por zero ou mais ocorrências de números e substitua-os por espaços em branco.
No segundo comando sed remova tudo o que vem seguido de (.) e também remova o próprio ponto (.).
Com rev e sed:
rev file| sed 's/.*[.]//' |rev
Exclua tudo antes do ponto(.) Também inclua e remova . em si.
Com grep:
grep -oP '.*(?=\.[0-9])' file
-o, --apenas correspondência Imprima apenas as partes correspondentes (não vazias) de uma linha correspondente, com cada parte em uma linha de saída separada. -P, --perl-regexp Interpretar PATTERN como uma expressão regular compatível com Perl (PCRE)
(?=pattern)
: Lookahead positivo: A construção de 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 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)
: Olhar para trás positivo. Um par de parênteses, com o parêntese de abertura seguido por um ponto de interrogação, um símbolo de “menor que” e um sinal de igual.
(?<=[0-9]\.).*
(lookbehind positivo) corresponde a tudo o que é seguido por qualquer ocorrência de números e termina com ponto (.).
No segundo comando grep, você pode usar o bacana \K
no lugar da afirmação lookbehind.
Com corte:
cut -f1 -d. file
cut -c 1-77 file # Print first 77 characters of each line.
cut - remove seções de cada linha de arquivos -d, --delimitador=DELIM use DELIM em vez de TAB para delimitador de campo -f, --campos=LISTA selecione apenas esses campos; -c, --caracteres=LISTA selecione apenas esses caracteres
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 eles tiverem comprimento fixo. O comando acima remove os dois últimos caracteres no final de cada linha no arquivo de entrada. comandos alternativos são ${line%??}
.
Responder2
Supondo que as extensões sejam todas de dígitos:
perl -pi -e 's/\.\d+$//' /path/to/file
-i
faz edição no local (como em sed
). \d
significa dígitos e $
denota o fim da linha.
Com awk
:
awk 'gsub(/\.[0-9]+$/,"")' /path/to/file
gawk
tem uma opção de edição local em versões mais recentes, mas não tenho certeza de quão portátil isso é. gsub
suporta um parâmetro opcional, especificando a coluna de destino:
awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file
A última forma tem o efeito colateral indesejado de separar cada coluna por um único espaço em sua saída, como se você tivesse feito isso print $1,..,$NF
. Eu não sei porque.
Responder3
Usá awk
-lo é 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
Responder4
Isso remove tudo que começa com o ponto:
sed 's/\..*//'