Êtes-vous prêt à utiliser la commande split? Sinon, vous pouvez facilement le faire avec une manipulation de texte directe, certainement en utilisant perl ou python. Tant que le fichier n'est pas trop faux, lisez-le en mémoire sous forme de chaîne, puis divisez la chaîne. Si le fichier est trop volumineux, un travail supplémentaire est nécessaire.
Faheem Mitha
@Faheem Mitha Le fichier est de 64 Mo. J'aime l'idée d'utiliser split car c'est plus rapide que d'écrire du code. Je me demandais maintenant si je spécifie le nombre de lignes correspondant à 70% du fichier, j'obtiens un gros fichier et un petit fichier. Ça ne devrait pas marcher?
aneuryzm
Et oui .. cela a fonctionné .. Dois-je supprimer la question?
Les commandes ci-dessous fonctionneront pour des pourcentages supérieurs à 50% (si vous souhaitez diviser uniquement en deux fichiers), approche rapide et sale.
Sur MacOSX, wc renvoie parfois le nombre de lignes avec un espace devant, quelque chose qui rompt ce script. La première tuyauterie vers xargs supprimera ces espaces et fera fonctionner à nouveau: split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
Emil Stenström
4
Vous pouvez utiliser csplitpour diviser en deux morceaux (en utilisant n'importe quel pourcentage), par exemple le premier morceau - les premiers 20% des lignes, le deuxième morceau - les 80% restants des lignes:
$(wc -l < infile): nombre total de lignes 2 / 10: pourcentage +1: ajoutez une ligne car elle csplitse diviseup to but not including line N
Cependant, vous ne pouvez fractionner que sur la base des lignes.
Fondamentalement, tant que vous avez le numéro de ligne via, $(( $(wc -l < file) * 2 / 10))vous pouvez utiliser n'importe quel outil orienté ligne:
sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile
... devrait fonctionner pour ce cas simple, car vous ne vous séparez qu'une fois - et c'est probablement splitun peu exagéré. Tant que le fichier est adressable, ddne fera que faire une seule read()sur <stdin, et ainsi catest laissé pour commencer son read()quel que soit le point de la ddlaisse.
Si le fichier est volumineux, alors un count=1 bs=$big_ol_numpourrait devenir un peu difficile à manier, et il peut être bloqué avec quelques calculs de shell supplémentaires - mais simples -.
Une entrée non seekable - comme d'un tuyau - Peut fausser dd« les résultats, bien que cela puisse être manipulé aussi bien w / GNU dds » iflag=fullblock.
Réponses:
Les commandes ci-dessous fonctionneront pour des pourcentages supérieurs à 50% (si vous souhaitez diviser uniquement en deux fichiers), approche rapide et sale.
1) répartir 70% sur la base des lignes
2) répartir 70% sur la base des octets
la source
split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
Vous pouvez utiliser
csplit
pour diviser en deux morceaux (en utilisant n'importe quel pourcentage), par exemple le premier morceau - les premiers 20% des lignes, le deuxième morceau - les 80% restants des lignes:$(wc -l < infile)
: nombre total de lignes2 / 10
: pourcentage+1
: ajoutez une ligne car ellecsplit
se diviseup to but not including line N
Cependant, vous ne pouvez fractionner que sur la base des lignes.
Fondamentalement, tant que vous avez le numéro de ligne via,
$(( $(wc -l < file) * 2 / 10))
vous pouvez utiliser n'importe quel outil orienté ligne:ou encore plus cool:
bien que certains
head
soient stupides et ne soient pas conformes aux normes , cela ne fonctionnera pas sur toutes les configurations ...la source
... devrait fonctionner pour ce cas simple, car vous ne vous séparez qu'une fois - et c'est probablement
split
un peu exagéré. Tant que le fichier est adressable,dd
ne fera que faire une seuleread()
sur<stdin
, et ainsicat
est laissé pour commencer sonread()
quel que soit le point de ladd
laisse.Si le fichier est volumineux, alors un
count=1 bs=$big_ol_num
pourrait devenir un peu difficile à manier, et il peut être bloqué avec quelques calculs de shell supplémentaires - mais simples -.Une entrée non seekable - comme d'un tuyau - Peut fausser
dd
« les résultats, bien que cela puisse être manipulé aussi bien w / GNUdd
s »iflag=fullblock
.la source
Le code suivant utilise
head
ettail
fonctionne avec n'importe quel rapport (40 à 60 dans ce cas):la source