Comment couper un fichier à une taille donnée sous Linux?

19

Je veux réduire la taille d'un fichier par force brute, c'est-à-dire que je ne me soucie pas du reste, je veux juste couper le fichier, disons de moitié, et jeter le reste.

La première chose qui me vient à l'esprit est le tronqué de Perl . Je suis l'exemple sur cette page et j'ai fait exactement la même chose:

seq 9 > test.txt
ls -l test.txt
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

Mais le fichier a toujours la même taille:

$ ls -lgG test.txt
-rw-rw---- 1 18 2013-08-08 09:49 test.txt

Comment puis-je faire fonctionner cela?

xpt
la source

Réponses:

62

Vous voudrez peut-être utiliser la commande tronquer :

truncate --size=1G test.txt

SIZE peut être spécifié en octets, Ko, K, Mo, M, etc. Je suppose que vous pouvez calculer la taille souhaitée à la main; sinon, vous pourriez probablement utiliser la commande stat pour obtenir des informations sur la taille actuelle du fichier.

ChrisInEdmonton
la source
Sa documentation (au format info) de coreutils.
Cristian Ciupitu
21
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

ouvre le fichier en lecture. Cependant, pour tronquer le fichier, vous devez le modifier, de sorte qu'un descripteur de fichier en lecture seule ne fonctionnera pas. Vous devez utiliser le mode "modifier" ( "+>").

Comme problème secondaire, cela m'étonne toujours lorsque les gens laissent les appels système échouer en silence et demandent ensuite ce qui n'a pas fonctionné. Une partie essentielle du diagnostic d'un problème consiste à examiner le message d'erreur produit; même si vous ne le comprenez pas, cela facilite la vie de ceux à qui vous demandez de l'aide.

Les éléments suivants auraient été un peu plus utiles:

perl -we 'open(FILE, "<", "./test.txt") or die "open: $!";
          truncate(FILE, 8) or die "truncate: $!";
          close(FILE);'

même s'il est vrai que cela n'aurait fait état que d'un "argument invalide". Pourtant, ce sont des informations utiles et pourraient bien vous avoir conduit à la conclusion que le mode ouvert était incorrect (comme il l'a fait pour moi).

rici
la source
3

Vous pouvez utiliser tailpour couper les 100 000 derniers octets, par exemple:

queue -c 100000 fichier> fichier2

-c affiche les 100 000 derniers octets du fichier, pour plus d'options:

queue d'homme

Pour remplacer le fichier d'origine par le fichier que vous venez de générer:

fichier mv file2

Ivan Malyshev
la source
2

La réponse ci-dessus citant tronquer est agréable. dd fera également le travail:

dd if=test.txt of=test2.txt bs=1 count=8
mv test2.txt test.txt
James Georgas
la source
1
La phrase clé est "à une taille donnée" , disons 1000. Je changerai la réponse à la plus votée à la place, qui fonctionne pour l'entrée à la volée - pas besoin d'un fichier intermédiaire.
2018
0

il y a une manière complètement différente de le faire, avec bash, en utilisant le programme ed. le script suivant ne conservera que les 5000 dernières lignes de tous les fichiers situés dans le répertoire spécifié. cela peut facilement être modifié pour boucler sur plusieurs répertoires, changer le nombre de lignes, etc.

#!/bin/bash

LOGDIR=/opt/log
SAVELINES=5000

dirs="$LOGDIR"
for dir in $dirs ; do
    files=${dir}/*
    for f in $files ; do
        echo -e "1,-${SAVELINES}d\nwq" | ed $f 1>/dev/null 2>&1
    done
done
Richard
la source