我有一个较大的文件(280列,700万行!),需要交换第一列和第二列。我认为可以使用awk循环打印$2,$1,然后是文件的结尾范围 - 但我不知道如何进行区间操作,并且我不能打印$2,$1,$3 ... $280!我在这里看到的大多数列交换答案都是特定于具有可管理列数的小文件的,因此我需要一些不依赖于指定每个列号的东西。
文件使用制表符分隔:
Affy-id chr 0 pos NA06984 NA06985 NA06986 NA06989
awk ' { t = $1; $1 = $2; $2 = t; print; } ' input_file
我在Windows系统上尝试使用Cygwin和一个制表符分隔的文件来尝试perreal的答案,但它无法正常工作,因为标准分隔符是空格。
如果你遇到相同的问题,可以尝试这个方法:
awk -F $'\t' ' { t = $1; $1 = $2; $2 = t; print; } ' OFS=$'\t' input_file
输入分隔符由-F $'\t'
定义,输出分隔符由OFS=$'\t'
定义。
awk -F $'\t' ' { t = $1; $1 = $2; $2 = t; print; } ' OFS=$'\t' input_file > output_file
OFS=$'\t'
参数了! - Atcoldawk '{printf("%s\t%s\n", $2, $1)}' inputfile
awk '{print $2 "\t" $1}' inputfile
。 - Fuujuhised -i 's/^\([^\t]*\t\)\([^\t]*\t\)/\2\1/' file
您尝试过使用cut命令吗?例如:
cat myhugefile | cut -c10-20,c1-9,c21- > myrearrangedhugefile
cat myhugefile | cut -f2,1
的输出结果与 cat myhugefile | cut -f1,2
相同。 - Hady Elsaharperl -pe 's/^(\S+)\t(\S+)/$2\t$1/;' file > outputfile
perl -F\\t -nlae 'print join("\t", @F[1,0,2..$#F])' inputfile
-F
参数指定分隔符。在大多数shell中,您需要在反斜杠前面再加一个反斜杠进行转义。在某些平台上,-F
自动意味着-n
和-a
,因此它们可以省略。-l
,因为最后一列出现在输出的最后。但如果在不同的情况下,如果最后一列需要出现在其他列之间,则必须删除换行符。 -l
开关会处理这个问题。"\t"
可以更改为任何其他内容,以在输出中生成不同的分隔符。
2..$#F
指定从第2列到最后一列的范围。正如您可能已经猜到的那样,在方括号内,您可以按所需顺序放置任何单个列或列范围。bash> while read col1 col2 rest; do
echo $col2 $col1 $rest
done <input_file
测试:
bash> echo "first second a c d e f g" |
while read col1 col2 rest; do
echo $col2 $col1 $rest
done
second first a b c d e f g
awk
无需使用临时变量进行交换:
echo '777777744444444464449: 317 647 14423 262927714037 : 0x2A29D5A1BAA7A95541' |
mawk '1; ($1 = $2 substr(_, ($2 = $1)^_))^_' FS=':' OFS=':'
777777744444444464449: 317 647 14423 262927714037 : 0x2A29D5A1BAA7A95541
317 647 14423 262927714037 :777777744444444464449: 0x2A29D5A1BAA7A95541
process.sh
的内容:#!/bin/bash
# inline Python script
read -r -d '' PYSCR << EOSCR
from __future__ import print_function
import codecs
import sys
encoding = "utf-8"
fn_in = sys.argv[1]
fn_out = sys.argv[2]
# print("Input:", fn_in)
# print("Output:", fn_out)
with codecs.open(fn_in, "r", encoding) as fp_in, \
codecs.open(fn_out, "w", encoding) as fp_out:
for line in fp_in:
# split into two columns and rest
col1, col2, rest = line.split("\t", 2)
# swap columns in output
fp_out.write("{}\t{}\t{}".format(col2, col1, rest))
EOSCR
# ---------------------
# do setup work?
# e. g. list files for processing
# call python script with params
python3 -c "$PYSCR" "$inputfile" "$outputfile"
# do some more processing
# e. g. rename outputfile to inputfile, ...
-F '\t'
时,制表符在最终输出中被吞掉了。有没有方法可以保留它们? - AtcoldOFS=$'\t'
。@perreal,也许值得更新答案以包含附加参数? - Atcoldawk '{ print $2, $1}'
它的意思是相同的。 - A.Villegas