dividindo uma linha em array no bash com tab como delimitador

1

Eu tenho um arquivo no seguinte formato e é separado por separadores

a   k   testis  adult   male    8 week  rRNA
b   k   testis  adult   male    8 week  rRNA
c   k   testis  adult   male    8 week  rRNA

Eu quero fazer alguma operação em cada linha, então estou usando um loop while.Eu quero dividir cada linha na guia e, em seguida, armazenar digamos 6 coluna que é 8 week em uma variável. Estou usando este código, mas não consigo obter o que desejo

while read -r line; do tmp=(${line///}); col6=${tmp[5]}; echo "$col6"; done < file.txt

Isso me dá 8 e não 8 week . 8 semanas tem um espaço entre 8 e semana e, portanto, quero dividir a linha na guia.

    
por user3138373 13.12.2017 / 19:02

1 resposta

7

A atribuição da matriz tmp=(${line///}) divide o valor em qualquer caractere IFS , que, por padrão, inclui guias, e espaços e novas linhas. (Não vejo o que a substituição vazia faz.) Para dividir apenas nas guias, defina IFS para isso:

foo=$'a\tk\testis\tadult\tmale\t8 week\tRNA'
IFS=$'\t'
tmp=($foo)
echo "${tmp[5]}"

Embora isso ainda pareça um problema, e como você já usa while read , você pode usar read -a tmp (pelo menos no Bash), ele divide a linha de entrada com base em IFS e separa os campos para elementos da matriz nomeada:

$ while IFS=$'\t' read -r -a tmp ; do
    echo "${tmp[5]}"
done <<< $'a\tk\testis\tadult\tmale\t8 week\tRNA'

Isso imprime 8 week . A outra vantagem é que a mudança em IFS só está em vigor pela duração do read , não pelo resto do script.

É claro que, se soubermos o número / significado dos campos, poderemos ter apenas read dividido para separar as variáveis nomeadas:

... IFS=$'\t' read -r col1 col2 col3 ...

Ou, se você quiser imprimir apenas essa coluna, use cut :

cut -d$'\t' -f 6  < file.txt
    
por 13.12.2017 / 19:15

Tags