Leia os números do arquivo de controle e extraia os números de linha correspondentes do arquivo de dados

Leia os números do arquivo de controle e extraia os números de linha correspondentes do arquivo de dados

Eu tenho um arquivo de controle - cntl.txt

2
3
5

Arquivo de dados - data.txt

red
blue
yellow
green
violet
orange

Preciso ler as linhas correspondentes do arquivo de controle, aqui a saída esperada é:

blue
yellow 
violet

Responder1

Exemplo de uma solução muito ineficiente:

for i in $(<control.txt); do awk -v c=$i 'NR~c{ print $0 }' data.txt; done;

Relato também uma boa solução que aprendi esta noite:

awk 'FNR==NR{ z[$0]++;next }; FNR in z' control.txt data.txt

Responder2

Usando apenasPOSIX especificadocaracterísticas do Sed:

sed -n -e "$(sed '/./s/$/p/' cntl.txt)" data.txt

É claro que se o seu cntl.txtarquivo tiver linhas além de números, você poderá receber um erro. Mas se tiver linhas vazias estas serão tratadas corretamente (ou seja, não afetarão a saída).

Responder3

Experimente isto:

join <(nl data.txt|sort -k1b,1) <(cat cntl.txt|sort -k1b,1) | sort -nk1,1 | cut -d' ' -f2-

nl - enumerará linhas para você

 1  red
 2  blue
 3  yellow
 4  green
 5  violet
 6  orange

| sort -k1b,1 - irá classificá-los pelo número da linha (primeiro campo), lexicograficamente

gato cntl.txt| sort -k1b,1 - classificará o arquivo de controle na mesma ordem

2
3
5

join <() <() - juntará os "dados" classificados (e numerados) com o "controle" classificado, no primeiro campo (ou seja, número da linha)

2 blue
3 yellow
5 violet

|sort -nk1,1 - reordenará os resultados numericamente (para colocar as linhas novamente em ordem)

| cut -d' ' -f2- - eliminará o campo do número da linha

blue
yellow
violet

Responder4

Outra solução possível:

IFS=$'\n' read -d '' -r -a colors < 'data.txt'; unset IFS;

for i in $(<cntl.txt); do
        echo ${colors[i-1]} 
done

A linha IFS configura o separador de arquivo interno como nova linha e insere cada linha de data.txt no array. Depois disso, você percorre as linhas em cntl.txt e imprime os elementos da matriz com determinado índice (menos 1 porque você inicia seu data.txt a partir de 1, não de 0, caso contrário, seria desnecessário).

informação relacionada