希望这很简单。
我有一个包含数百列的文本文件。只需要复制其中的8个(不是连续),将它们移动到第5,第6,第7列......然后像以前那样将文件的其余部分移动到第5,6,7列......
我真的不想写出一个包含356个列占位符的awk或cut命令。
谢谢!
更新 - 示例:
A B C D E F G ... X Y Z
我想要的是:
A Y K L Z J B C D E F G ... X Y Z
感谢您的帮助。
哦,这些字母实际上代表由标签分隔的整个列。
答案 0 :(得分:0)
有人这样吗?
awk '{$5=$70;$6=$35;$7=$122;$8=$190;$9=$55;$10=$200;$11=$12;$12=$67}1' file
编辑: 这会将某些列移动到位置6到8,然后删除原始位置。
cat file
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
awk '{a[++i]=$0} END {for (i=1;i<=5;i++) printf "%s ",a[i];printf "%s %s %s ",a[16],a[8],a[22];a[16]=a[8]=a[22]="";for (i=6;i<=27;i++) printf "%s ",a[i]}' RS="[ \t]" file | awk '{$1=$1}1' OFS="\t"
A B C D E P H V F G I J K L M N O Q R S T U W X Y Z
EDIT2:一个更干净的版本
awk '
{
a[++i]=$0
}
END {
for (i=1;i<=5;i++)
printf "%s\t",a[i]
printf "%s\t%s\t%s\t",a[16],a[8],a[22]
a[16]=a[8]=a[22]=""
for (i=6;i<=27;i++)
if (a[i])
printf "%s\t",a[i]
}
' RS="[[:space:]]" file
EDIT3:如果awk
不支持此类RS
,请使用此解决方案
awk '
{
for (i=1;i<=NF;i++)
a[i]=$i
}
END {
for (i=1;i<=5;i++)
printf "%s\t",a[i]
printf "%s\t%s\t%s\t",a[16],a[8],a[22]
a[16]=a[8]=a[22]=""
for (i=6;i<=27;i++)
if (a[i])
printf "%s\t",a[i]
}
' file
答案 1 :(得分:0)
根据您的comment,这可能适合您:
awk '{FS=OFS="\t"} $7=$7 FS $116 FS $119 FS $121 FS $124 FS $127 FS $129 FS $131 FS $134 FS $137 FS $140 FS $143 FS $146 FS $149 FS $152 FS $155 FS $158' inputfile
编辑:如果你有一个标题,你可以说:
awk 'NR>1 {FS=OFS="\t"} $7=$7 FS $116 FS $119 FS $121 FS $124 FS $127 FS $129 FS $131 FS $134 FS $137 FS $140 FS $143 FS $146 FS $149 FS $152 FS $155 FS $158' inputfile
答案 2 :(得分:0)
这个移动字段而不是复制,但不能有空字段。
无需迭代1-NF,您可以将字段附加到$ 1并通过将它们设置为“”来删除它们,但是您在“孔”中有双重标签。幸运的是,假设您没有任何空字段,可以使用tr
删除这些内容。
awk 'BEGIN{FS=OFS="\t"}
{
$7=$7"\t"$116"\t"$119"\t"$121"\t"$124"\t"$127"\t"$129"\t"$131"\t"$134"\t"$137"\t"$140"\t"$143"\t"$146"\t"$149"\t"$152"\t"$155"\t"$158
$116=$119=$121=$124=$127=$129=$131=$134=$137=$140=$143=$146=$149=$152=$155=$158=""
print
}' infile | tr -s "\t" >outfile