Answers:
您可以使用一个小的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))
如果您不介意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$
一种使用方式 awk
。
内容infile
:
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
运行以下awk
命令:
awk '{
## Variable 'i' will be incremented from first field, variable 'j'
## will be decremented from last field. And their values will be exchanged.
## The loop will end when both values cross themselves.
j = NF;
for ( i = 1; i <= NF; i++ ) {
if ( j - i < 1 ) {
break;
}
temp = $j;
$j = $i;
$i = temp;
j--;
}
print;
}' infile
结果如下:
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
这很慢,但确实具有一项兑换功能。当字段分隔符比单个字符宽时,它将保持宽度。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
您可以使用tac
只需要在输入前后进行转置。这可以通过电子表格计算器sc
及其助手来完成psc
:
< infile psc -S -r | sc -W% - | tac | psc -S -r | sc -W% - > outfile
如这里所见。
当所有列均已填充时,此方法效果最佳。
文件内
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 B C D E F G H I J K L
超越
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
L K J I H G F E D C B A
正如PeterO 所指出的那样,sc
硬限制为702列,因此这是此方法支持的最大大小。
1
-> 1.00
。另外,对于超过702个字段的行,我也会收到错误消息。它似乎与32768的数字限制有关...但是,这很快。
-S
到psc
命令中应该将所有内容解释为字符串。关于702列限制,这是一个硬限制,因为仅支持A到ZZ列(26 + 26 * 26),我将对此添加一条注释。
这个管道比最快的其他答案要快得多,这是一个重要因素(请参见结果)。它使用tr
和tac
。它确实需要利用数据中不存在的2个ASCII字节(\ x00- \ x7F)。
\x00
通常是一个不错的选择,因为 \x01
但是您可以使用不在数据中的任何ASCII字节。
在此的示例SPACE和TAB作为分隔符。分隔符可以是多字节或单个。输出定界符为单个空格。
这是命令。文件名显示numberof fields
_xnumber of lines
<"$file" tr ' \t\n' '\0\0\1' |tr -s '\0' '\n' |tac |tr '\n' ' ' |tr '\1' '\n'
如果要/需要检查未使用的字节,则可以使用此可选awk
脚本事先进行检查。即使运行此可选脚本,总的时间仍然比其他方法要快得多(到目前为止:)。这是预处理脚本。
o=($(<"$file" char-ascii-not-in-stream)); x="${o[0]}"; y="${o[1]}"
<"$file" tr ' \t\n' "$x$x$y" |tr -s "$x" '\n' |tac |tr '\n' ' ' | tr '$y' '\n' >"$file".$user
这是awk脚本: char-ascii-not-in-stream
#!/usr/bin/awk -f
{c[$0]} END{for(i=0;i<=127;i++) {if(sprintf("%c", i) in c);else {printf "\\%03o ",i}}}
对于此脚本,第二组时间包括char-ascii-not-in-stream
的时间。
Peter.O {tr,tac,tr} ==== file_10_x10000
real 0m0.013s 0m0.015s
user 0m0.020s 0m0.020s
sys 0m0.008s 0m0.012s
user11136 {python} ===== file_10_x10000
real 0m0.057s
user 0m0.048s
sys 0m0.008s
jmp {python} =========== file_10_x10000
real 0m0.160s
user 0m0.160s
sys 0m0.000s
rush {awk} ============= file_10_x10000
real 0m0.121s
user 0m0.120s
sys 0m0.000s
##############################################
Peter.O {tr,tac,tr} ==== file_1000_x1000
real 0m0.048s 0m0.059s
user 0m0.040s 0m0.040s
sys 0m0.040s 0m0.048s
user11136 {python} ===== file_1000_x1000
real 0m0.158s
user 0m0.136s
sys 0m0.028s
jmp {python} =========== file_1000_x1000
real 0m0.327s
user 0m0.320s
sys 0m0.008s
rush {awk} ============= file_1000_x1000
real 0m0.832s
user 0m0.820s
sys 0m0s012s
##############################################
Peter.O {tr,tac,tr} ==== file_1000000_x50
real 0m5.221s 0m6.458s
user 0m4.208s 0m5.248s
sys 0m2.624s 0m2.396s
user11136 {python} ===== file_1000000_x50
real 0m16.286s
user 0m10.041s
sys 0m5.148s
jmp {python} =========== file_1000000_x50
real 0m22.845s
user 0m20.705s
sys 0m1.140s
rush {awk} ============= file_1000000_x50
real 0m44.793s
user 0m43.583s
sys 0m0.848s
##############################################
perl -lane 'print join " ", reverse @F'