Lê os números do arquivo de controle e extrai os números de linha correspondentes do arquivo de dados

6

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
    
por Parthi 02.11.2016 / 21:58

5 respostas

5

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
    
por 02.11.2016 / 22:21
4

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).

    
por 02.11.2016 / 22:52
3

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
    
por 02.11.2016 / 22:21
2

Com sed apenas:

sed -n "$(sed -e 's/$/p;/' < cntl.txt)" data.txt
    
por 02.11.2016 / 22:41
-1

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).

    
por 02.11.2016 / 22:49