Extrai as duas primeiras partes de cada linha usando o awk

1

Eu tenho um arquivo delimitado por espaço que se parece com isso:

0   22:16050847:T:C 0   16050847
0   rs62224609:16051249:T:C 0   16051249
0   22:16051250:G:A 0   16051250
0   GSA-rs138295790 0   16057310

Como posso modificar a segunda coluna para extrair apenas as duas primeiras partes? Gostaria que minha saída fosse assim:

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310
    
por user233014 25.05.2017 / 12:48

5 respostas

2

Abordagem curta awk :

awk '{split($2,a,":"); $2=(length(a)>1)? a[1]":"a[2] : $2}1' file

A saída:

0 22:16050847 0 16050847
0 rs62224609:16051249 0 16051249
0 22:16051250 0 16051250
0 GSA-rs138295790 0 16057310
  • split($2,a,":") - divide o segundo campo no array a pelo separador :
por 25.05.2017 / 13:07
1

Se você tem o GNU awk:

gawk '{split($2,a,/[:-]/,c); $2 = sprintf("%s%c%s", a[1], c[1], a[2])} 1' file
0 22:16050847 0 16050847
0 rs62224609:16051249 0 16051249
0 22:16051250 0 16051250
0 GSA-rs138295790 0 16057310
    
por 25.05.2017 / 13:07
0

com perl :

perl -lpe 's/^\S+\s+[^:]+:[^:]+\K\S+//' file

Com o GNU sed :

sed -E ':t s/:\w+//2; tt' file

Saída:

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310
    
por 25.05.2017 / 13:12
0

Isso deve funcionar, supondo que seu arquivo seja chamado de my_file e você esteja usando o shell bash. Deve ser mais fácil de entender e aplicar a problemas semelhantes:

paste -d ' ' <(awk '{print $1}' my_file) \
  <(awk '{print $2}' my_file | sed 's/:.:.//' ) \
  <(awk '{print $3" "$4}' my_file)

Portanto, para cada linha das entradas, paste mescla as seções subsequentes com um delimitador de espaço, fornecido por <() .

  • A primeira seção do awk obtém a primeira entrada da coluna
  • A segunda seção awk pega a coluna do meio e remove a segunda coluna, removendo qualquer: T: C como parte
  • O terceiro extrai as colunas restantes.

O resultado é:

0 22:16050847  0 16050847
0 rs62224609:16051249  0 16051249
0 22:16051250 0 16051250
0 GSA-rs138295790 0 16057310
    
por 25.05.2017 / 12:58
0

Bash:

while read -r f1 f2 rest; do
   printf '%s' "$f1" "$(expr " $f2" : '\([^:]*:[^:]*\).*' \| " $f2")" "$rest"; echo
   # the lone echo provides for the newline
done < yourfile

read dividirá os campos em $f1 , $2 e todos os restantes serão agrupados no $rest . Em seguida, no segundo campo, $f2 , executamos expr para extrair os primeiros e segundos campos delimitados por dois pontos. Se isso não for possível, acabamos usando a própria variável $f2 .

Sed:

sed -e '
   s/[^[:space:]]\{1,\}/\
&\
/2
   :loop
      s/\n\(.*:.*\):.*\n/\n\n/
   tloop
   s/\n//g
' yourfile

Primeiro, envolvemos o segundo campo com \n e, em seguida, executamos um loop em torno dessa região até que restem apenas dois campos (ou um delimitador de campo).

Perl:

perl -pe 's/\G[^:\h]+:[^:\h]+\K\S+//,next while /\S\h+\S/g' yourfile

perl -pe 's/^\h*\S+\h+(?:(?!:)\S)+:(?:(?!:)\S)+\K\S+//' yourfile

perl -F'(\h+)' -lane '
   /:/ and $_ = join ":", (/[^:]+/g)[0,1] for $F[/^\h/?4:2];
   print @F;
' yourfile

Resultado

0   22:16050847 0   16050847
0   rs62224609:16051249 0   16051249
0   22:16051250 0   16051250
0   GSA-rs138295790 0   16057310
    
por 27.05.2017 / 19:09

Tags