J'ai des données CSV / tabular dans un fichier, comme: (Ce ne sont pas toujours des chiffres, des valeurs séparées par des virgules aléatoires. Les nombres à un chiffre sont plus faciles à Un exemple, cependant.) p> Je veux mélanger 40% de l'une des colonnes. À titre d'exemple, disons le 3ème. Donc, peut-être que 3 et 1 sont échangés les uns avec les autres. Maintenant, la troisième colonne est la suivante: p> J'essaie de le faire en place dans un fichier à partir d'un script code> bash code> que je travaille sur, Et je n'ai pas beaucoup de chance. Je continue à errer de manière assez folle et infructueuse i tagué cette question avec une litanie de choses parce que je ne suis pas tout à fait sûr de quel ou des outils que je devrais même utiliser pour cela. P> EDIT: STRUT> Je vais probablement finissent par accepter la réponse de Rubens ', aussi Wacky, car elle contient directement le concept d'échange (que je suppose que j'aurais pu accentuer davantage dans la question initiale), et cela me permet de spécifier un pourcentage de la colonne pour échanger. Il arrive également de travailler, ce qui est toujours un avantage. P> pour quelqu'un qui n'a pas besoin de cela, et veut juste un shuffle de base, la réponse de Jim Garrison fonctionne également (je l'ai testée). P> Un mot d'avertissement, cependant, sur la solution de Rubens. J'ai pris ceci: p> supprimé le grep code> des trous de lapin qui me laissent penser que je vais avoir le mauvais sens (l'échec constant est ce qui me tire dessus). P>
printf "\ n"; code> et déplacé la nouvelle ligne de caractère comme ceci: p>
for (i = 1; i <= NF; ++i) {
delim = (i != NF) ? "," : "\n";
...
}
3 Réponses :
Cela fonctionnera pour une colonne spécifiquement désignée, mais devrait suffire à vous pointer dans la bonne direction. Cela fonctionne sur des coquilles de bash modernes, y compris Cygwin: la fonctionnalité opératoire est " Substitution de processus ". P> La commande code> La commande joint des fichiers horizontalement et les trois pièces sont scindées du fichier d'origine via Cut CODE>, avec la deuxième pièce (la colonne à aléomiser) exécutée via la commande
shuf code> pour réorganiser les lignes. Voici la sortie de l'exécution plusieurs fois: p>
+1 shuf code> doit probablement être remplacé par un shuffler personnalisé pour gérer la contrainte de 40%, mais sinon agréable (en supposant un nombre fixe de colonnes).
sortie d'impression: p>
n code> paires, à partir de
1 code> à
Nombre de lignes code> et la valeur correspondante dans la ligne (pour la colonne sélectionnée ), puis triez-la au hasard; li>
num_random = pourcentage * num_lines / 100 code>; li>
num_random code> Entrées de votre vecteur randomisé; Li>
$ ./script.sh infile 3 40
1,7,3,2
8,3,8,0
4,9,1,3
8,5,7,3
5,6,5,9
J'utiliserais une approche de 2 passes qui commence par avoir un nombre de lignes et lisez le fichier dans un tableau, puis utilisez la fonction RAND () d'AWK () pour générer des numéros aléatoires pour identifier les lignes que vous modifiez. et ensuite rand () à nouveau pour déterminer quelles paires de ces lignes vous échangeront puis échangez les éléments de la matrice avant d'imprimer. Quelque chose comme ce pseudo-code, algorithme rugueux:
La randomisation n'est pas la force des outils de traitement de texte tels que
sed code> ou
awk code>.
Vous souhaitez sélectionner 40% des colonnes et mélanger complètement ceux-ci, ou sélectionnez une colonne (ou plus) et mélanger 40% de ses lignes?
Ce dernier (40% des rangées dans une colonne).
En plus de dépasser ne pas être un point fort, l'édition de lieu est totalement et totalement impossible en utilisant l'un des utilitaires marqués. Un outil externe serait requis - et les standards sont très pauvres. Vous avez besoin d'une vraie langue.
L'utilisation de SED / AWK est-elle autorisée?
@ormaaj fyi vous pouvez faire "en place édition" avec SED, Awk ou Bash. Considérez le fichier
SED -I 'S / FOO / BAR /' FILE CODE> Par exemple.
Modification «in-place» signifie simplement que les détails du fichier temporaire sont manipulés pour vous. Quoi qu'il en soit, cette tâche nécessite de conserver le fichier entier en mémoire, en apportant des modifications pouvant impliquer toutes les lignes, puis la rédaction de l'écart.
SED CODE> et
AWK CODE> sont conçus pour traiter la ligne de ligne, sans avoir à se rappeler toutes les lignes précédant la ligne actuelle.
@Edmorton awk et bash ne peuvent certainement pas. IIRC Le responsable de GAWK ne souhaitait pas inclure une option sur place car elle n'est tout simplement pas l'outil de travail. Bash ne peut pas lsek, ce qui le rend assez impossible. Le mieux que vous puissiez faire dans Bash est des astuces comme l'ouverture d'une lecture / écriture FD, à l'aide de
Lisez -n code> pour rechercher à droite et redéfinir la FD avec
/ dev / dev / fd / n code> pour rembobiner. Vraiment le seul shell qui a les primitives nécessaires pour ce type d'opération de fichier est ksh93 (en utilisant
<# ((()) code>,
<< # code>,
>; / Code> etc), et c'est assez douloureux, même alors.
@ORMAAJ - Pour être clair, nous ne parlons pas de réel "en place" édition (que Bash peut faire, par la manière - voir les réponses à ma récente question sur le sujet dans Comp.unix.shell) Nous parlons À propos de quelqu'un appelle un outil pour fonctionner sur un fichier d'entrée et une fois l'outil effectué en exécution, le fichier d'entrée a changé. À partir d'un point de vue des utilisateurs, il est fonctionnellement équivalent à une édition «in-place» true et l'un des outils que j'ai mentionnés peut faire cela. Misté: GAWK obtiendra une option d'édition sur place spécifique
GAWK -IINPLACE CODE>, équivalent fonctionnellement à
SED -I code>, dans une version à venir.
@Edmorton qui serait une sorte de gentille. Au moins AWK fournit un moyen sûr d'injecter des variables de shell.
SED -I CODE> est tout simplement très inadéquat. Je me penche vers l'utilisation de Python (comme le module code> MMAP code> et de belles abstractions telles que MemoryView) ou un script VIM, jusqu'à ce que peut-être un jour, quelqu'un écrit et standardise un éditeur non interactif décent à mi-chemin. Bien que je supporterai mon commentaire à propos de Bash, même avec des fichiers temporaires. Cela fait longtemps que j'ai vu une nouvelle technique de manipulation de fichiers intéressante.