Exemplo de uma solução muito ineficiente:
for i in $(<control.txt); do awk -v c=$i 'NR~c{ print $0 }' data.txt; done;
Eu também relato uma boa solução que aprendi hoje à noite:
awk 'FNR==NR{ z[$0]++;next }; FNR in z' control.txt data.txt
Eu tenho um arquivo de controle - cntl.txt
2
3
5
Arquivo de dados - data.txt
red
blue
yellow
green
violet
orange
Eu preciso ler as linhas correspondentes do arquivo de controle, aqui a saída esperada é:
blue
yellow
violet
Exemplo de uma solução muito ineficiente:
for i in $(<control.txt); do awk -v c=$i 'NR~c{ print $0 }' data.txt; done;
Eu também relato uma boa solução que aprendi hoje à noite:
awk 'FNR==NR{ z[$0]++;next }; FNR in z' control.txt data.txt
Usando apenas os POSIX especificados recursos do Sed:
sed -n -e "$(sed '/./s/$/p/' cntl.txt)" data.txt
Claro que se o seu arquivo cntl.txt
tiver linhas além de números, você poderá receber um erro. Mas se houver linhas vazias, elas serão tratadas corretamente (ou seja, elas não afetarão a saída).
Tente isto:
join <(nl data.txt|sort -k1b,1) <(cat cntl.txt|sort -k1b,1) | sort -nk1,1 | cut -d' ' -f2-
nl - irá enumerar linhas para você
1 red
2 blue
3 yellow
4 green
5 violet
6 orange
| sort -k1b, 1 - irá ordená-los pelo número da linha (primeiro campo), lexicograficamente
cat cntl.txt | sort -k1b, 1 - ordenará o arquivo de controle na mesma ordem
2
3
5
junte-se < () < () - irá juntar os "dados" ordenados (e numerados) com o "controlo" ordenado, no primeiro campo (ou seja, o número da linha)
2 blue
3 yellow
5 violet
| sort -nk1,1 - irá reordenar os resultados numericamente (para colocar as linhas novamente em ordem)
| cut -d '' -f2- - irá soltar o campo do número da linha
blue
yellow
violet
Com sed
apenas:
sed -n "$(sed -e 's/$/p;/' < cntl.txt)" data.txt
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 interno de arquivos como nova linha e insere cada linha de data.txt no array. Depois disso, você passa pelas linhas em cntl.txt e imprime os elementos da matriz com um dado índice (menos 1 porque você inicia seu data.txt de 1, não de 0, caso contrário, seria desnecessário).
Tags text-processing awk sed