Comment puis-je diviser un fichier texte en 70% et 30% en utilisant la commande split?
Comment puis-je diviser un fichier texte en 70% et 30% en utilisant la commande split?
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
split -l $[ $(wc -l filename|cut -d" " -f1) * 70 / 100 ] filename
2) répartir 70% sur la base des octets
split -b $[ $(wc -c filename|cut -d" " -f1) * 70 / 100 ] filename
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:
csplit infile $(( $(wc -l < infile) * 2 / 10 + 1))
$(wc -l < infile)
: nombre total de lignes
2 / 10
: pourcentage
+1
: ajoutez une ligne car elle csplit
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:
sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile
ou encore plus cool:
{ head -n$(( $(wc -l < infile) * 2 / 10)) > 20-infile; cat > 80-infile; } <infile
bien que certains head
soient stupides et ne soient pas conformes aux normes , cela ne fonctionnera pas sur toutes les configurations ...
{ BS=$(($(wc -c <file) * $P / 100))
dd count=1 bs="$BS" >file1; cat
} <file >file2 2>/dev/null
... 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 seule read()
sur <stdin
, et ainsi cat
est laissé pour commencer son read()
quel que soit le point de la dd
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 / GNU dd
s » iflag=fullblock
.
Le code suivant utilise head
et tail
fonctionne avec n'importe quel rapport (40 à 60 dans ce cas):
export FILE_NAME=train.vw
head -n $[ $(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100 ] ${FILE_NAME} > train_40.vw
tail -n +$[ ($(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100) + 1 ] ${FILE_NAME} > train_60.vw