Unix 如何在shell脚本中打印特定列数?

Unix 如何在shell脚本中打印特定列数?,unix,sed,awk,Unix,Sed,Awk,我有一个文本文件temp1,它有20多列,它的数值如下所示 1,0,3,0,5........, 1,0,5,0,8........, 3,0,6,0,3........, 5,0,6,0,4........, ................., 我想删除总计(和)为零的列,我需要将剩余列重定向到新文件 例如,如上所述,第2列和第4列的总数为零,因此我需要删除第2列和第4列,并将其重定向到单独的文件 有人能帮我吗?你可以使用awk:(以下内容很难看,但我希望可读。这就是目标。我让更好的awk

我有一个文本文件temp1,它有20多列,它的数值如下所示

1,0,3,0,5........,
1,0,5,0,8........,
3,0,6,0,3........,
5,0,6,0,4........,
.................,
我想删除总计(和)为零的列,我需要将剩余列重定向到新文件

例如,如上所述,第2列和第4列的总数为零,因此我需要删除第2列和第4列,并将其重定向到单独的文件

有人能帮我吗?

你可以使用awk:(以下内容很难看,但我希望可读。这就是目标。我让更好的awkist进一步增强/减少它)

如果数据位于文件
/path/to/zefile
中:

awk -F',' '  
      FNR==NR { for (col=1;col<=NF;col++)
                   { if ($col != 0) 
                        {wewantthiscolumn[col]=1 } 
                   }
                next
              }

              { for (col=1;col<=NF;col++) 
                   { if (wewantthiscolumn[col]==1) 
                        { printf ("%s,",$col) } 
                   }
                print "" 
              }' /path/to/zefile /path/to/zefile | sed -e 's/,$//'
1,0,3,0,5,0
1,0,5,0,8,1
3,0,6,0,3,2
5,0,6,0,4,5
我不想假设任何列都不能为空,因此我使用“DELETETHIS”确保只删除相关字段。。。但这意味着第1种方法实际上更简单^^:只打印您需要的字段,然后去掉行尾的“,”。

您可以使用awk:(以下内容很难看,但我希望可读。这就是目标。我让更好的awkist进一步增强/减少它)

如果数据位于文件
/path/to/zefile
中:

awk -F',' '  
      FNR==NR { for (col=1;col<=NF;col++)
                   { if ($col != 0) 
                        {wewantthiscolumn[col]=1 } 
                   }
                next
              }

              { for (col=1;col<=NF;col++) 
                   { if (wewantthiscolumn[col]==1) 
                        { printf ("%s,",$col) } 
                   }
                print "" 
              }' /path/to/zefile /path/to/zefile | sed -e 's/,$//'
1,0,3,0,5,0
1,0,5,0,8,1
3,0,6,0,3,2
5,0,6,0,4,5

我不想假设任何列都不能为空,因此我使用“DELETETHIS”确保只删除相关字段。。。但这意味着第1种方法实际上更简单^^:只打印所需的字段,然后去掉行尾的“,”。

使用python的解决方案:

#!/usr/bin/env python

def transpose(grid):
    return zip(*grid)

def removeBlankRows(grid):
    return [list(row) for row in grid if any(map(int,row))]

grid = []
with open("input.csv") as fd:
    for line in fd:
        grid.append(line.strip().split(','))

data = removeBlankRows(transpose(removeBlankRows(transpose(grid))))

for i in data:
    print ",".join(i)
输入:

1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,1,4
输出:

1,3,5
1,5,8
3,6,3
5,6,4
1,3,0,5
1,5,0,8
3,6,0,3
5,6,1,4
输入:

1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,1,4
输出:

1,3,5
1,5,8
3,6,3
5,6,4
1,3,0,5
1,5,0,8
3,6,0,3
5,6,1,4

使用python的解决方案:

#!/usr/bin/env python

def transpose(grid):
    return zip(*grid)

def removeBlankRows(grid):
    return [list(row) for row in grid if any(map(int,row))]

grid = []
with open("input.csv") as fd:
    for line in fd:
        grid.append(line.strip().split(','))

data = removeBlankRows(transpose(removeBlankRows(transpose(grid))))

for i in data:
    print ",".join(i)
输入:

1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,1,4
输出:

1,3,5
1,5,8
3,6,3
5,6,4
1,3,0,5
1,5,0,8
3,6,0,3
5,6,1,4
输入:

1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,1,4
输出:

1,3,5
1,5,8
3,6,3
5,6,4
1,3,0,5
1,5,0,8
3,6,0,3
5,6,1,4

这里有一种使用
awk
的方法。运行方式如下:

awk -f ./script.awk file{,}
script.awk的内容

BEGIN {
    FS=","
}

FNR==NR {
    for(i=1;i<=NF;i++) {
        if ($i != 0) {
            a[i]
        }
    }
    next
}

{
    for(j=1;j<=NF;j++) {
        if (j in a) {
            printf "%s%s", $j, (j==NF ? RS : FS)
        }
    }
}
结果:

1,3,5,0
1,5,8,1
3,6,3,2
5,6,4,5

这里有一种使用
awk
的方法。运行方式如下:

awk -f ./script.awk file{,}
script.awk的内容

BEGIN {
    FS=","
}

FNR==NR {
    for(i=1;i<=NF;i++) {
        if ($i != 0) {
            a[i]
        }
    }
    next
}

{
    for(j=1;j<=NF;j++) {
        if (j in a) {
            printf "%s%s", $j, (j==NF ? RS : FS)
        }
    }
}
结果:

1,3,5,0
1,5,8,1
3,6,3,2
5,6,4,5
$cat文件
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
$awk-f tst.awk文件
1,3,5
1,5,8
3,6,3
5,6,4
$cat tst.awk
开始{FS=“,”}
{
对于(j=1;j
$cat文件
1,0,3,0,5
1,0,5,0,8
3,0,6,0,3
5,0,6,0,4
$awk-f tst.awk文件
1,3,5
1,5,8
3,6,3
5,6,4
$cat tst.awk
开始{FS=“,”}
{

对于(j=1;jI将窃取您的
printf“%s%s”,$j,(j==NF?RS:FS)
对于我的解决方案,因为我喜欢这个想法,但后来我意识到这意味着如果最后一列的和为零,那么它就不会打印结尾换行符,因此每一行都会被连接起来,因此在这种特殊情况下它将不起作用。不过,感谢下一次的想法。啊,现在我想起了这个解决方案让我感到困扰的是什么-它会出现在记录1的字段中有
-1
,在记录2的同一字段中有
1
的t列,因为这两个列的值都不为零,但它们的总和为零,因此该列应该被删除。我要偷取你的
printf“%s%s”$j,(j==NF?RS:FS)
对于我的解决方案,因为我喜欢这个想法,但后来我意识到这意味着如果最后一列的和为零,那么它就不会打印结尾换行符,因此每一行都会被连接起来,因此在这种特殊情况下它将不起作用。不过,感谢下一次的想法。啊,现在我想起了这个解决方案让我感到困扰的是什么-它会出现t在记录1的字段中有
-1
的列和在记录2中的同一字段中有
1
的列,因为这两个列的值都不是零,但它们的总和是零,因此该列应该被删除。如果第1行字段2的值不是零,而第2行字段2的值不是零,则应d第2列是否打印?我假设不是,因为该列的和仍然是零,但请澄清,最好是通过更新上面的输入/输出来显示这种情况。如果第1行字段2的值
-1
而不是零,并且第2行字段2的值
1
而不是零,那么第2列是否应该打印?我假设不是因为和f或者该列仍然为零,但请澄清,最好是通过更新上面的输入/输出来显示该情况。Hi all thanx for the update不幸我的系统崩溃了其工作正常。Hi all thanx for the update不幸我的系统崩溃了其工作正常。