Suppression efficace de l'en-tête sur place pour les gros files à l'aide de sed?

Les commands ci-dessous peuvent prendre des minutes dépend de la taille du file. Y a-t-il une méthode plus efficace?

sed -i 1d large_file 

Essayez plutôt ed :

 ed <<< $'1d\nwq' large_file 

Si ce "grand" signifie environ 10 millions de lignes ou plus, mieux utiliser la tail . N'est pas capable de l'édition sur place, mais sa performance rend ce manque à pardonner:

 tail -n +2 large_file > large_file.new 

Modifier pour afficher des différences de time:

(code awk par Jaypal ajouté pour avoir des time d'exécution sur la même machine (CPU 2.2GHz).)

 bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped bash-4.2$ time sed -i 1d bigfile.txt time 0m4.318s bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt time 0m0.533s bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt time 0m0.626s bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; } time 0m0.034s bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; } time 0m0.328s 

Il n'y a aucun moyen de supprimer efficacement les choses du début d'un file. La suppression des données depuis le début nécessite la réécriture du file entier.

Tronquer à partir de la fin d'un file peut être très rapide (le operating system ne doit ajuster que les informations de taille de file, éventuellement en supprimant les blocs inutilisés). Cela n'est généralement pas possible lorsque vous essayez de supprimer de la tête d'un file.

Il pourrait théoriquement être "rapide" si vous avez supprimé un bloc / étendue entière, mais il n'y a pas d'appels système pour cela, vous devrez donc vous baser sur la sémantique spécifique au système de files (si tel est le cas). (Ou avoir une certaine forme de décalage à l'intérieur du premier bloc / étendue pour marquer le vrai début du file, je suppose.) Jamais entendu parler de cela non plus.)

Vous pouvez utiliser Vim en mode Ex:

 ex -sc '1d|x' large_file 
  1. 1 select la première ligne

  2. d supprimer

  3. x sauvegarder et fermer

La méthode la plus efficace, ne le faites pas! Si vous le faites, en tout cas, vous avez besoin de deux fois le «grand» espace sur le disque, et vous perdez les IO.

Si vous êtes coincé avec un gros file que vous voulez lire sans la 1ère ligne, attendez que vous ayez besoin de le lire pour supprimer la 1ère ligne. Si vous devez envoyer le file de stdin à un programme, utilisez la queue pour le faire:

 tail -n +2 | your_program 

Lorsque vous avez besoin de lire le file, vous pouvez en profiter pour supprimer la 1ère ligne, mais seulement si vous avez l'espace nécessaire sur le disque:

 tail -n +2 | tee large_file2 | your_program 

Si vous ne pouvez pas lire à partir de stdin, utilisez un fifo:

 mkfifo large_file_wo_1st_line tail -n +2 large_file > large_file_wo_1st_line& your_program -i large_file_wo_1st_line 

de mieux encore si vous utilisez bash, profitez de la substitution de process:

 your_program -i <(tail -n +2 large_file) 

Si vous avez besoin de chercher dans le file, je ne vois pas une meilleure solution que de ne pas être coincé avec le file en premier lieu. Si ce file a été généré par stdout:

 large_file_generator | tail -n +2 > large_file 

Sinon, il y a toujours la solution FIFO ou de substitution de process:

 mkfifo large_file_with_1st_file large_file_generator -o large_file_with_1st_file& tail -n +2 large_file_with_1st_file > large_file_wo_1st_file large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file) 

C'est juste théoriser, mais …

Un système de files personnalisé (implémenté à l'aide de FUSE ou d'un mécanisme similaire) peut exposer un directory dont le contenu est exactement le même qu'un directory déjà existant ailleurs, mais avec des files tronqués comme vous le souhaitez. Le système de files traduirait tous les décalages de files. Ensuite, vous n'auriez pas à faire une réécriture fastidieuse d'un file.

Mais étant donné que cette idée est très non sortingviale, à less d'avoir des dizaines de téraoctets de tels files, la mise en place d'un tel système de files serait trop coûteuse et trop longue pour être pratique.