Swap deux colonnes – awk, sed, python, perl

J’ai des données dans un gros fichier (280 colonnes de large, 7 millions de lignes de long!) Et je dois échanger les deux premières colonnes. Je pense que je pourrais le faire avec une sorte de awk for loop, pour imprimer $ 2, $ 1, puis une plage à la fin du fichier – mais je ne sais pas comment faire la partie range et je ne peux pas imprimer $ 2 , 1 $, 3 $ … 280 $! La plupart des réponses à l’échange de colonnes que j’ai vues ici sont spécifiques à de petits fichiers avec un nombre de colonnes gérable. J’ai donc besoin de quelque chose qui ne dépend pas de la spécification de chaque numéro de colonne.

Le fichier est délimité par des tabulations:

Affy-id chr 0 pos NA06984 NA06985 NA06986 NA06989 

Vous pouvez le faire en permutant les valeurs des deux premiers champs:

 awk ' { t = $1; $1 = $2; $2 = t; print; } ' input_file 

J’ai essayé la réponse de perreal avec cygwin sur un système Windows avec un fichier séparé par des tabulations. Cela n’a pas fonctionné, car le séparateur standard est l’espace.

Si vous rencontrez le même problème, essayez plutôt ceci:

 awk -F $'\t' ' { t = $1; $1 = $2; $2 = t; print; } ' OFS=$'\t' input_file 

Le séparateur entrant est défini par -F $'\t' et le séparateur pour la sortie par OFS=$'\t' .

 awk -F $'\t' ' { t = $1; $1 = $2; $2 = t; print; } ' OFS=$'\t' input_file > output_file 

Avez-vous essayé d’utiliser la commande cut? Par exemple

 cat myhugefile | cut -c10-20,c1-9,c21- > myrearrangedhugefile 

Cela pourrait fonctionner pour vous (GNU sed):

 sed -i 's/^\([^\t]*\t\)\([^\t]*\t\)/\2\1/' file 

Essayez ceci plus pertinent pour votre question:

 awk '{printf("%s\t%s\n", $2, $1)}' inputfile 

C’est aussi facile en perl:

 perl -pe 's/^(\S+)\t(\S+)/$2\t$1/;' file > outputfile 

Vous pouvez le faire en Perl:

 perl -F\\t -nlae 'print join("\t", @F[1,0,2..$#F])' inputfile 

Le -F spécifie le délimiteur. Dans la plupart des coquilles, vous devez faire précéder une barre oblique inverse d’une autre pour y échapper. Sur certaines plates-formes, -F implique automatiquement -n et -a afin qu’elles puissent être supprimées.

Pour votre problème, vous n’avez pas besoin d’utiliser -l car les dernières colonnes apparaissent en dernier dans la sortie. Mais si dans une situation différente, si la dernière colonne doit apparaître entre les autres colonnes, le caractère de nouvelle ligne doit être supprimé. Le commutateur -l s’en charge.

Le "\t" dans la jointure peut être changé en n’importe quoi d’autre pour produire un délimiteur différent dans la sortie.

2..$#F spécifie une plage de 2 jusqu’à la dernière colonne. Comme vous l’avez peut-être deviné, à l’intérieur des crochets, vous pouvez placer n’importe quelle colonne ou plage de colonnes dans l’ordre souhaité.