我有 1000 列的大文件。我想重新排列,以便最后一列应该是第三列。为此我使用过,
cut -f1-2,1000,3- file > out.txt
但这不会改变顺序。
任何人都可以帮助使用 cut 或 awk 吗?
另外,我想重新排列第 10 列和第 11 列,如下所示:
例子:
1 10 11 2 3 4 5 6 7 8 9 12 13 14 15 16 17 18 19 20
试试这个 awk 单线:
awk '{$3=$NF OFS $3;$NF=""}7' file
这是将最后一列移至第三列。如果你有 1000 个,那么它会使用第 1000 个 col。
编辑
如果文件是制表符分隔的,您可以尝试:
awk -F'\t' -v OFS="\t" '{$3=$NF OFS $3;$NF=""}7' file
编辑2
添加一个例子:
kent$ seq 20|paste -s -d'\t'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
kent$ seq 20|paste -s -d'\t'|awk -F'\t' -v OFS="\t" '{$3=$NF OFS $3;$NF=""}7'
1 2 20 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
编辑3
您没有给出任何输入示例。所以假设您在原始文件中没有空列。(没有连续的多标签):
kent$ seq 20|paste -s -d'\t'|awk -F'\t' -v OFS="\t" '{$3=$10 FS $11 FS $3;$10=$11="";gsub(/\t+/,"\t")}7'
1 2 10 11 3 4 5 6 7 8 9 12 13 14 15 16 17 18 19 20
毕竟我们可以循环打印这些字段。
我想你想要的是:
awk 'BEGIN{FS=OFS="\t"} {$3=$NF OFS $3; sub(OFS "[^" OFS "]*$","")}1' file
这也可能对您有用,具体取决于您的 awk 版本:
awk 'BEGIN{FS=OFS="\t"} {$3=$NF OFS $3; NF--}1' file
如果没有分号后面的部分,您的输出中将有尾随制表符。
由于很多人都在寻找这个,即使是最好的 awk 解决方案也不是很漂亮和易于使用,我想发布我用 Python 编写的解决方案(mycut):
#!/usr/bin/env python3
import sys
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)
#example usage: cat file | mycut 3 2 1
columns = [int(x) for x in sys.argv[1:]]
delimiter = "\t"
for line in sys.stdin:
parts = line.split(delimiter)
print("\t".join([parts[col] for col in columns]))
我考虑添加 cut 的其他功能,例如更改分隔符和使用 * 打印剩余列的功能。但随后它将获得一个自己的页面。
awk
使用更简单语法的 ' 的 shell 包装函数:
# Usage: rearrange int_n [int_o int_p ... ] < file
rearrange ()
{
unset n;
n="{ print ";
while [ "$1" ]; do
n="$n\$$1\" \" ";
shift;
done;
n="$n }";
awk "$n" | grep '\w'
}
例子...
echo foo bar baz | rearrange 2 3 1
bar baz foo
使用bash
大括号扩展,rearrange
按降序排列第一个和最后 5 个项目:
echo {1..1000}a | tr '\n' ' ' | rearrange {1000..995} {5..1}
1000a 999a 998a 997a 996a 995a 5a 4a 3a 2a 1a
在/bin中排序的 3 个字母的 shell :
ls -lLSr /bin/?sh | rearrange 5 9
150792 /bin/csh
154072 /bin/ash
771552 /bin/zsh
1554072 /bin/ksh