Como extrair uma linha específica em um arquivo de texto múltiplo em um único arquivo txt no linux?

-1

Eu tenho arquivos 5000 txt com os diferentes dados abaixo. Eu preciso de um script de shell para copiar apenas a linha 11 (última linha) deles em um único arquivo e classificá-los do menor para o maior.

por exemplo:

arquivo1.txt

1KE5.pdb
USER_CHARGES
INVALID_CHARGES
@<TRIPOS>ATOM
ATOM      1  N   MET A   1   40.880  54.110  11.190  1.00  0.00
ATOM      8  HB1 MET A   1   38.760  53.510   9.880  1.00  0.00
ATOM      9  HB2 MET A   1   39.700  52.020   9.980  1.00  0.00
1            40.7               

arquivo2.txt

1KW5.pdb                     
USER_CHARGES                 
INVALID_CHARGES              
@<TRIPOS>ATOM                
ATOM      6  HA  MET A   1   39.020  54.080  12.120  1.00  0.00
ATOM      7  CB  MET A   1   39.050  52.700  10.580  1.00  0.00
ATOM      8  HB1 MET A   1   38.760  53.510   9.880  1.00  0.00
2            33.7               

file3.txt

1KW5.pdb                     
USER_CHARGES                 
INVALID_CHARGES              
@<TRIPOS>ATOM                
ATOM      4  H3  MET A   1   40.580  54.900  10.580  1.00  0.00
ATOM      5  CA  MET A   1   39.750  53.360  11.780  1.00  0.00
ATOM      6  HA  MET A   1   39.020  54.080  12.120  1.00  0.00
3            54.2               

Eu preciso que a saída seja:

Final.txt

1       40.7
2       33.7
3       54.2

Eu preciso de um script para resolver esse problema. Obrigado por qualquer ajuda que você possa dar.

    
por H. aryapour 13.07.2016 / 14:50

3 respostas

0

Você pode usar find para obter os arquivos de entrada, tail para obter o final dos arquivos e sort para classificá-los. Por exemplo:

find /path/to/ -name "file*.txt" -type f -exec tail -n1 {} \; | sort --numeric-sort --output output.txt

Onde /path/to/ é o caminho para seus arquivos, file*.txt é o padrão de seus nomes de arquivos, -type f encontra apenas arquivos, não diretórios, -n1 informa a tail para retornar 1 linha e output.txt é o arquivo de saída.

    
por 13.07.2016 / 15:58
2

Dependendo do que você considera mais consistente, da 11ª linha ou da última linha, você pode usar sed ou tail , respectivamente. Eu preferiria sed , pois ele lida com vários arquivos de forma mais limpa e também garante que os arquivos com menos linhas sejam incluídos. Então, você precisaria apenas de uma lista de seus arquivos. Isso poderia ser feito com globbing, se eles estão todos no mesmo diretório, ou com find se eles estiverem aninhados abaixo disso.

Portanto, com find e sed :

find /path/to/your/files -type f -name '*.txt' -exec sed -n 11p {} + >> output.txt

O mesmo com tail , observe o uso de \; em vez de + para que cada arquivo seja tratado separadamente:

find /path/to/your/files -type f -name '*.txt' -exec tail -n1 {} \; >> output.txt

Ou talvez globbing:

sed -n 11p /path/to/your/files/*.txt >> output.txt
    
por 13.07.2016 / 15:33
0

** I need a shell script to copy only ... last line of them into a single file and sort them from smallest to largest.

Como seus arquivos de exemplo não possuem uma linha 11, trabalhei com base na sua "(última linha)".

  • vários arquivos de texto com um padrão de nomenclatura comum.
  • última linha
  • classificar
  • colocar em um arquivo

Para reunir as últimas linhas e classificá-las

$ tail -q -n 1 file*.txt | sort
1            40.7
2            33.7
3            54.2

e, para classificar os resultados e colocar os resultados em um arquivo

$ tail -q -n 1 file*.txt | sort > final.txt
$ cat final.txt
1            40.7
2            33.7
3            54.2

Isso pressupõe que os arquivos estão todos em um diretório.

Se os arquivos estiverem em subdiretórios em um nível, altere file*.txt para */file*.txt

Se os arquivos estiverem em vários diretórios aninhados de várias profundidades, ou em vários locais, você deverá usar o comando find , conforme descrito em outras respostas.

$ find . -name 'file*.txt' -exec tail -q -n 1 {} \; | sort
1            40.7
2            33.7
3            54.2

onde os nomes dos arquivos podem incluir espaços, o que costumava ser um problema.

$ ls -F *.txt
file1.txt  file2.txt  file three.txt  final.txt
    
por 13.07.2016 / 15:50