Ferramenta de linha de comando para extrair linhas de um arquivo de texto [duplicado]

0

Eu tenho um arquivo grande (digamos reads.fasta ) que tem cerca de 5.000.000 linhas e tenho outro arquivo reads_of_interest que contém uma lista dos números de linha de reads.fasta que eu quero extrair.

Existe um método de linha de comando fácil para fazer isso?

Em outras palavras, existe um arquivo large_file.txt . Existe outro arquivo line_numbers.txt que é da forma

12 
134
1456

E eu quero extrair as linhas 12 , 134 , 1456 de large_file.txt . O número de linhas que eu quero extrair é da ordem de 500.000.

Obrigado!

    
por Devil 05.12.2015 / 00:50

2 respostas

3

Esta é uma maneira fácil e direta de conseguir o que você deseja. O problema aqui é que todo o large_file.txt será verificado. Se isso for muito lento, há outras coisas para tentar. Uma delas seria carregar o arquivo em um banco de dados digitado nos números de linha, o que daria uma recuperação extremamente rápida em comparação com a varredura do arquivo.

#!/bin/sh
awk '
    NR == FNR {
        for (i=1; i<=NF; i++) {
            linenums[$i]
        }
    }
    NR != FNR {
        if (FNR in linenums) {
            print
        }
    }
' line_numbers.txt large_file.txt

NR é o número do registro atual (Número de registros) e FNR é o número do registro atual no arquivo atual.

Então, quando NR == NFR awk está processando o primeiro arquivo arg, quando NR != NFR awk está processando o segundo arquivo (ou posterior).

Isso lê todos os números de linha de line_numbers.txt e os armazena como chaves em uma matriz sem elementos de dados, somente chaves (a matriz linenums ).

Quando o segundo arquivo, large_file.txt , estiver sendo lido, se o número do registro atual tiver sido armazenado como uma chave na matriz linenums , a linha de large_file.txt será impressa.

O método de procurar os números de linha na matriz linenums é relativamente rápido porque awk usa um algoritmo de hash interno para procurar as chaves.

    
por 05.12.2015 / 01:08
1

Assumindo que file_numbers.txt contenha uma única linha e se essa linha não for muito grande, o seguinte deve funcionar

sed -n "$(<file_numbers.txt sed -e "s/ /p;/g" -e "s/$/p/")" large_file.txt
    
por 05.12.2015 / 02:24