Fractionnez un fichier par ligne et contrôlez l'extension des fichiers résultants

28

Il existe une commande standard pour le fractionnement de fichiers - fractionner.

Par exemple, si je veux diviser un fichier de mots en plusieurs morceaux de 10000 lignes, je peux utiliser:

split -dl 10000 words wrd

et il générerait plusieurs fichiers de la forme wrd.01, wrd.02 et ainsi de suite.

Mais je veux avoir une extension spécifique pour ces fichiers - par exemple, je veux obtenir les fichiers wtd.01.txt, wrd.02.txt.

Y a-t-il un moyen de le faire?

Rogach
la source

Réponses:

12

Pas avec split, mais vous pouvez facilement les renommer par la suite, ou vous pouvez le faire dans awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile
Kevin
la source
Semble bon - mais ne fonctionne pas. Dans votre formulaire, se plaint de "l'expression pour la redirection" >> "a une valeur de chaîne nulle", et si "fichier" est "changé" en "nom de fichier", sort les fichiers de la forme wrd. {Numéro de fichier}. {Numéro de ligne} .txt (beaucoup d'entre eux :)
Rogach
@Rogach Désolé, je ne l'avais pas testé, alors j'ai oublié que awk ne fait pas de division entière. J'ai testé celui-ci.
Kevin
49

Ce n'était pas disponible à l'époque mais avec des versions plus récentes ( ≥ 8.16), gnu spliton peut utiliser le --additional-suffixcommutateur pour contrôler l'extension résultante. De man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

donc lorsque vous utilisez cette option:

split -dl 10000 --additional-suffix=.txt words wrd

les pièces résultantes se termineront automatiquement par .txt:

wrd00.txt
wrd01.txt
.........
don_crissti
la source
3
Ne fonctionne pas sur mac
ericgu
2
J'adore ton sarcasme. Je suis un unix n00b du monde Apple. J'utilise OS X Yosemite et je ne voulais tout simplement pas que les autres plantent et brûlent comme je l'ai fait. J'ai testé et examiné dans la documentation et nous n'avons pas ce paramètre. J'ai peut-être raté quelque chose. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu
5
@swiftshokunin - ma réponse concerne gnu split, une partie de gnu coreutils. Il est également disponible sur OSX si vous installez coreutilsvia homebrewmais notez que par défaut, sur OSX, les gnuutilitaires ont un gpréfixe à leur nom (par exemple gstatau lieu de stat) donc vous l'invoquez comme gsplit(ou modifiez le CHEMIN selon le guide ici si vous voulez pour l'utiliser comme splitsur l'OSX split). HTH.
don_crissti
1
Bonne réponse. sous OS X, utilisez gsplitpour faire fonctionner les suffixes numériques (-d).
Brent Faust
1
wow, je ne savais pas qu'il y a gsplit - il provient probablement de coreutils mentionnés ci-dessus et il a - suffixe supplémentaire. Merci à tous ceux qui ont commenté cette solution :)
Łukasz Rysiak
13

Ces tâches sont mieux gérées avec le shell. Utilisez le fractionnement puis écrivez une boucle simple pour renommer les fichiers. Par exemple

for file in wrd.*
do
    mv "$file" "$file.txt"
done

renommerait vos fichiers wrd.01, wrd.02, etc. afin qu'ils aient tous une extension .txt.

Kyle Jones
la source
C'est assez évident, mais cela briserait la concision du script bash.
Rogach
1
La philosophie Unix est de vous fournir un ensemble d'outils simples que vous combinez ensuite pour faire un travail. La «concision du script bash» n'était pas une exigence déclarée dans votre question.
Kyle Jones
7
PS: le split+mvcombo est plus de 6 fois plus rapide que awk(environ 3s vs 18s ) pour un fichier d'entrée de 10 millions de lignes (75 Mo) ... le texte de chaque ligne était son propre numéro de ligne ... Merci d'avoir redéclaré le "évident" :)
Peter.O
3
PPS: Je viens de vérifier cela un peu plus loin. La différence de vitesse est liée au nombre de fichiers créés par rapport au nombre de formats et de calculs arithmétiques effectués par awk pour chaque ligne quel que soit le nombre de fichiers de sortie ... En utilisant le même fichier d'entrée que l'exemple ci-dessus: Lorsqu'il y a 100 fois moins de fichiers, split + mvc'est 75 fois plus rapide que awk: Lorsqu'il y a 100 fois plus de fichiers, split + mvc'est 1,5 fois plus rapide que awk. Donc, pour moi, cette split + mvméthode gagne haut la main. C'est comme consice (sans doute plus), et est plus rapide que awk.
Peter.O
1
si vous êtes préoccupé par la longueur de 5 lignes, essayez ceci à la place: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony