Fractionner un fichier en deux fichiers sur une ligne donnée

12

Je cherche un moyen sous Unix de diviser un fichier en deux fichiers à un numéro de ligne donné.

split -l 100 file_nameest proche de ce que je recherche, mais cette commande crée plusieurs fichiers, chacun de 100 lignes. Je recherche une commande pour diviser un fichier en deux fichiers à un numéro de ligne donné. Existe-t-il un moyen de le faire sous Unix?

tortue
la source

Réponses:

13

Une solution un peu plus stricte:

(head -100 > f1.txt; cat > f2.txt) < input.txt
Rubens
la source
1
Belle solution. Pas de comptage avec wcavant et le fichier d'entrée n'est toujours traité qu'une seule fois, comme avec la awksolution.
Dubu
2
Il y a une légère chance que headplus de 100 lignes soient lues afin de trouver les 100 premières lignes vers lesquelles sortir f1.txt; ces octets supplémentaires ne seront pas vus par cat.
chepner
C'est tellement lent
sdaffa23fdsf
12

Utilisez awk, de sorte que vous devez effectuer un seul passage dans le fichier d'entrée. Ce qui suit suppose que vous voulez les 122 premières lignes dans le premier fichier et les autres dans le second.

awk 'NR < 123 { print >> "top_file"; next } {print >> "bottom_file" }' file_name
chepner
la source
Cela mérite un coup de pouce. si vous voulez diviser un fichier de X en Y, c'est le plus simple.
Glenn Plas
C'est la solution la plus simple à comprendre. Fonctionné comme un charme ... et me fait penser que je devrais essuyer la poussière de mon livre O'Reilly Sed & Awk que j'ai depuis 1999 environ, la section sed est bien lue, la section awk pas tellement.
Michael
C'est mieux que la solution exceptée pour la raison @chepner mentionnée dans les commentaires. Vous perdrez des caractères dans le fichier 'f2.txt'. Cette solution est précise et efficace. awk ftw.
Goran
7

Vous pouvez utiliser headet tailpour obtenir les deux parties:

head -n K file_name > top_file
tail -n L file_name > bottom_file

Kest le numéro de ligne et le Lnombre de lignes à partir du bas (nombre total de lignes - K).

(vous pouvez obtenir le nombre total de lignes en utilisant wc -l file_name).

jh314
la source
5

Vous pouvez utiliser csplit(si disponible) pour le faire:

csplit file N+1

divisera le fichier en deux morceaux, un morceau jusqu'au numéro de ligne (et y compris) Net l'autre morceau du numéro de ligne N+1jusqu'à la dernière ligne.
Si vous souhaitez diviser (mais sans inclure) le numéro de ligne N:

csplit file N
don_crissti
la source
C'est super! Merci, cela a parfaitement résolu le problème pour moi.
Zertrin
Meilleure performance pour diviser un fichier de 20 Go en morceaux.
dr0i
@ dr0i - pas étonnant, csplitest optimisé pour ce travail.
don_crissti
Fractionnement d'un fichier de 200 millions de lignes, je me suis «épuisé la mémoire» en utilisant un csplit datant de 2008. En utilisant csplit daté de 2011, cela fonctionne :)
dr0i
4

Les deux headet tailont des options pour produire des lignes à partir de "l'autre" fin du fichier que ce ne serait le cas autrement. Vous avez donc ces deux options:

head -n 100 source.txt > file1.txt
head -n -100 source.txt > file2.txt

ou (où NNN est inférieur de 100 à la sortie de wc -l source.txt):

tail -n +NNN source.txt > file1.txt
tail -n NNN source.txt > file.txt

Vous pouvez lire les pages de manuel de vos versions de headet tailpour plus d'informations.

Twalberg
la source
0

Vous pouvez utiliser «wc», «dc», «head» et «tail». C'est à dire

unix> wc -l foo
545 /tmp/foo
unix> dc -e '545 100 - p'
445
unix> head -n 100 foo > filea
unix> tail -n 445 foo > fileb

Pour faciliter l'utilisation, vous pouvez transformer ci-dessus en un script shell.


la source