我有一个包含列的文件。请参阅下面的示例:
a b c ... z
1 2 3 ... 26
我想交换所有列,其中第一列成为最后一列,第二列成为最后一列......等等。
z y x ... a
26 25 24 ... 1
有没有一个衬垫(awk
或sed
)可以做到这一点?
我知道awk
当只有几列时可以使用,但我希望能够对具有数千列的文件执行此操作。
tac
这对线条来说非常完美。
我想我正在寻找列的等效项。
rev
对我不起作用,因为它还会交换列中的内容。
答案1
awk '{for(i=NF;i>0;i--)printf "%s ",$i;print ""}' file
答案2
你可以用一个小的 python 脚本来做到这一点:
#!/usr/bin/env python
# Swaps order of columns in file, writes result to a file.
# usage: program.py input_file output_file
import sys, os
out = []
for line in open(sys.argv[1], 'r'):
fields = line.split()
rev = ' '.join(list(reversed(fields)))
out.append(rev)
f = open(sys.argv[2], 'w')
f.write(os.linesep.join(out))
答案3
如果你不介意 python,那么这个单行代码将反转每一行中空格分隔列的顺序:
paddy$ cat infile.txt
a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
a e i o u
paddy$ python3 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$
上面的代码也适用于 python2.7:
paddy$ python2.7 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$
答案4
虽然速度很慢,但它确实有一个可取之处。当字段分隔符比单个字符宽时,它会保持字段分隔符的宽度。 FWIW:如果运行此脚本两次,结果与原始结果相同。
这是脚本。
awk '{ eix = length($0)
for( fn=NF; fn>0; fn--) { dix=eix
while( substr($0,dix,1) ~ /[ \t]/ ) dix--
printf "%s%s", substr($0,dix+1,eix-dix), $fn
dix-=length($fn); eix=dix }
print substr($0,1,dix)
}' "$file"
下面是一些时间比较。测试文件包含 1 行。
fields fields
10,0000 10,000,000
user11136 {python} | real 0.029s real 3.235s
reversible? no | user 0.032s user 2.008s
| sys 0.000s sys 1.228s
jmp {python} | real 0.078s real 5.045s
reversible? no | user 0.068s user 4.268s
| sys 0.012s sys 0.560s
rush {awk} | real 0.120s real 10.889s
reversible? no | user 0.116s user 8.641s
| sys 0.008s sys 2.252s
petero {awk} | real 0.319s real 35.750s
reversible? yes | user 0.304s user 33.090s
| sys 0.016s sys 2.660s