web-dev-qa-db-fra.com

Échangez deux colonnes - awk, sed, python, perl

J'ai des données dans un gros fichier (280 colonnes de large, 7 millions de lignes!) Et j'ai besoin d'échanger les deux premières colonnes. Je pense que je pourrais le faire avec une sorte de boucle awk for, pour imprimer $ 2, $ 1, puis une plage à la fin du fichier - mais je ne sais pas comment faire la partie plage, et je ne peux pas imprimer $ 2 , 1 $, 3 $ ... 280 $! La plupart des réponses d'échange de colonnes que j'ai vues ici sont spécifiques aux petits fichiers avec un nombre gérable de colonnes, 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
49
Charley Farley

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

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

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
19
emi-le

Essayez ceci plus pertinent pour votre question:

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

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

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

Cela pourrait fonctionner pour vous (GNU sed):

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

C'est aussi facile en Perl:

Perl -pe 's/^(\S+)\t(\S+)/$2\t$1/;' file > outputfile
3
Aaron Lawson

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 obus, vous devez faire précéder une barre oblique inverse d'une autre pour y échapper. Sur certaines plateformes -F implique automatiquement -n et -a afin qu'ils puissent être supprimés.

Pour votre problème, vous n'auriez 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 d'autres colonnes, le caractère de nouvelle ligne doit être supprimé. Le -l switch s'en charge.

Le "\t" in join peut être remplacé par 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é.

2
Loax