我有一个大文件中的数据(280列宽,700万行!)我需要交换前两列。我想我可以使用某种类型的awk for循环,打印$ 2,$ 1,然后一个范围到文件的末尾 - 但我不知道如何做范围部分,我不能打印$ 2 ,1美元,3美元...... 280美元!我在这里看到的大多数列交换答案都特定于具有可管理列数的小文件,所以我需要的东西不依赖于指定每个列号。
该文件以制表符分隔:
Affy-id chr 0 pos NA06984 NA06985 NA06986 NA06989
答案 0 :(得分:83)
您可以通过交换前两个字段的值来完成此操作:
awk ' { t = $1; $1 = $2; $2 = t; print; } ' input_file
答案 1 :(得分:19)
我在带有制表符分隔文件的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
答案 2 :(得分:4)
这可能适合你(GNU sed):
sed -i 's/^\([^\t]*\t\)\([^\t]*\t\)/\2\1/' file
答案 3 :(得分:4)
尝试这与您的问题更相关:
awk '{printf("%s\t%s\n", $2, $1)}' inputfile
答案 4 :(得分:3)
您是否尝试过使用cut命令? E.g。
cat myhugefile | cut -c10-20,c1-9,c21- > myrearrangedhugefile
答案 5 :(得分:3)
这在perl中也很容易:
perl -pe 's/^(\S+)\t(\S+)/$2\t$1/;' file > outputfile
答案 6 :(得分:2)
您可以在Perl中执行此操作:
perl -F\\t -nlae 'print join("\t", @F[1,0,2..$#F])' inputfile
-F
指定分隔符。在大多数shell中,您需要在反斜杠之前与另一个反弹以逃避它。在某些平台-F
会自动隐含-n
和-a
,因此可以删除它们。
对于您的问题,您不需要使用-l
,因为最后一列显示在输出的最后一列。但是,如果在不同的情况下,如果最后一列需要出现在其他列之间,则必须删除换行符。 -l
开关负责处理此问题。
连接中的"\t"
可以更改为其他任何内容,以在输出中生成不同的分隔符。
2..$#F
指定从2到最后一列的范围。您可能已经猜到,在方括号内,您可以按所需顺序放置任何单列或列范围。
答案 7 :(得分:1)
除了您的外壳程序外,无需调用其他任何东西
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
答案 8 :(得分:0)
甚至使用“ inlined” Python-就像在Shell脚本中的Python脚本中一样-但,仅当您想要事前或事后用Bash做更多脚本时...否则会不必要地复杂。
脚本文件Table
的内容:
process.sh
如果只需要交换单个文件的列,则也可以只创建一个Python脚本并静态定义文件名。或者只是使用上面的答案。