使用awk或sed重新排列具有空值的列

时间:2015-08-19 05:42:06

标签: linux awk sed multiple-columns

我想重新排列txt文件的列,但是有空值,这会导致问题。例如:

testfile的:

Name    ID      Count   Date    Other
A       1       10      513     x
        6       15      312     x
        3       18      314     x
B       19      31      942     x
        8       29      722     x

当我尝试$ more testfile |awk '{print $2"\t"$1"\t"$3"\t"$4"\t"$5}'时 它变成了:

ID      Name    Count   Date    Other
1       A       10      513     x
15      6       312     x
18      3       314     x
19      B       31      942     x
29      8       722     x

这不是我想要的,请帮助,我希望它是

ID      Name    Count   Date    Other
1       A       10      513     x
15              6       312     x
18              3       314     x
19      B       31      942     x
29              8       722     x

此外我不确定哪些列可能包含空值,并且列长度不固定,谢谢

3 个答案:

答案 0 :(得分:2)

假设您的输入文件不是以制表符分隔的,并且您有(或可以获得)GNU awk,那么我建议:

$ awk -v FIELDWIDTHS="8 8 8 8 8" -v OFS='\t' '{
    for (i=1;i<=NF;i++) {
        gsub(/^\s+|\s+$/,"",$i)
    }
    t=$1; $1=$2; $2=t'
}1' file
ID      Name    Count   Date    Other
1       A       10      513     x
6               15      312     x
3               18      314     x
19      B       31      942     x
8               29      722     x

如果您的文件是以制表符分隔的,那么您只需要:

awk 'BEGIN{FS=OFS="\t"} {t=$1; $1=$2; $2=t}1' file

答案 1 :(得分:1)

show notification使用的最自然的模型是由白色空间到非白色空间和背面的过渡定义的列。由于您的列本身可能是空白空间,因此自然模型无法正常工作。

但是,您可以恢复使用基于列位置的模型而不是转换,这意味着只包含空格的文件(选项卡的存在会使事情变得复杂):

appdelegate

仍然可以重新排列,但不像基于过渡的列那样简洁。

以下awk脚本可以解决问题,交换Name ID Count Date Other A 1 10 513 x 6 15 312 x 3 18 314 x B 19 31 942 x 8 29 722 x awk

name

如果原始文件被调用id并且{ name = substr($0, 1,7); id = substr($0, 9,7); count = substr($0,17,7); date = substr($0,25,7); other = substr($0,33 ); print id" "name" "count" "date" "other; } 脚本存储在pax.in中,则命令awk将根据需要为您提供:

pax.awk

请记住,我已经编写了相对灵活的脚本,允许您非常轻松地更改列的顺序。如果您只想交换前两列,则可以使用:

awk -f pax.awk pax.in

或略短(如果您允许使用其他工具):

ID      Name    Count   Date    Other
1       A       10      513     x
6               15      312     x
3               18      314     x
19      B       31      942     x
8               29      722     x

答案 2 :(得分:1)

另一个awk替代方案是使用字段数。如果你知道你的数据并且它只是第一栏中的缺陷,你可以试试这个。

awk -v OFS="\t" 'NF==4{$5=$4;$4=$3;$3=$2;$2=$1;$1=""} {print $2,$1,$3,$4,$5}'

但是,输出将以制表符分隔而不是固定长度格式。你可以使用printf和更改OFS来实现相同的功能,但也许tab分隔是表格表示所需要的。