改进csv文件的bash脚本

改进csv文件的bash脚本,bash,awk,Bash,Awk,我在一个文件夹中有一堆CSV文件。它们都在同一个结构上。超过2k列。第一列是ID 我需要为每个文件执行以下操作: 对于每个n奇数列(第一列除外),执行以下操作: 如果n值为0,则对于所有行,删除n列和n-1列 如果n值为100,则删除所有行的n列 打印已删除列的索引 我有以下代码: for f in *.csv; do awk 'BEGIN { FS=OFS="," } NR==1 { for (i=3; i<=NF; i+=2)

我在一个文件夹中有一堆CSV文件。它们都在同一个结构上。超过2k列。第一列是ID

我需要为每个文件执行以下操作: 对于每个n奇数列(第一列除外),执行以下操作:

  • 如果
    n
    值为0,则对于所有行,删除
    n
    列和
    n-1
  • 如果
    n
    值为100,则删除所有行的n列
  • 打印已删除列的索引
我有以下代码:

for f in *.csv; do
        awk 'BEGIN { FS=OFS="," }
        NR==1 {
      for (i=3; i<=NF; i+=2)
         a[i]
     }FNR==NR {
           for (i=1; i<=NF; i++)
              sums[i] += $i;
           ++r;
           next
        } {
           for (i=1; i<=NF; i++)
              if (sums[i] > 0 && sums[i+1]>0 && sums[i] != 100*r)
                 printf "%s%s", (i>1)?OFS:"", $i;
              else print "removed index: " i > "removed.index"
              print ""
   }' "$f"  "$f" > "new_$f"
done 
电流输出(坏):

预期产出:

23232,1,33
21232,1,33
23132,1,33
23212,1,33
24232,1,33
27232,1,33

有人可以检查问题出在哪里吗?

您需要从逻辑中跳过第一列,以检查前一列中的0:

awk 'BEGIN{FS=OFS=","; out=ARGV[1] ".removed.index"}
FNR==NR {
   for (i=1; i<=NF; i++)
      sums[i] += $i;
   ++r;
   next
} FNR==1 {
   for (i=3; i<=NF; i++) {
      if (sums[i] == 0) {
         if (i-1 in sums) {
            delete sums[i-1];
            print "removed index: " (i-1) > out
         }
         delete sums[i];
         print "removed index: " i > out
      } else if (sums[i] == 100*r) {
         delete sums[i];
         print "removed index: " i > out
      }
   }
} {
   printf "%s", $1
   for (i=2; i<=NF; i++)
      if (i in sums)
         printf "%s%s", OFS, $i;
   printf "%s", ORS
} END{close(out)}' file file
删除的索引还包括:

cat file.removed.index

cat removed.index
removed index: 2
removed index: 3
removed index: 4
removed index: 5
removed index: 7
removed index: 8
removed index: 9
removed index: 11

很抱歉反应太晚。是的,输出的csv文件现在是正确的。但是,索引打印存在一个问题。根据上面示例的索引文件,删除的索引为:8、9、11,但假设为2、3、4、5、7、8、9、11。现在可以了。非常感谢你的帮助。最后一件小事-我不希望removed.index的文件名将根据原始文件名命名:
originalFileName.removed.index
。当前,文件被一次又一次地覆盖。我尝试过使用
${f}\u removed.index
,但不起作用。你太棒了。非常感谢你的帮助。我从你身上学到了很多。希望有一天能像你一样好:)
awk 'BEGIN{FS=OFS=","; out=ARGV[1] ".removed.index"}
FNR==NR {
   for (i=1; i<=NF; i++)
      sums[i] += $i;
   ++r;
   next
} FNR==1 {
   for (i=3; i<=NF; i++) {
      if (sums[i] == 0) {
         if (i-1 in sums) {
            delete sums[i-1];
            print "removed index: " (i-1) > out
         }
         delete sums[i];
         print "removed index: " i > out
      } else if (sums[i] == 100*r) {
         delete sums[i];
         print "removed index: " i > out
      }
   }
} {
   printf "%s", $1
   for (i=2; i<=NF; i++)
      if (i in sums)
         printf "%s%s", OFS, $i;
   printf "%s", ORS
} END{close(out)}' file file
23232,1,33
21232,1,33
23132,1,33
23212,1,33
24232,1,33
27232,1,33
cat file.removed.index

cat removed.index
removed index: 2
removed index: 3
removed index: 4
removed index: 5
removed index: 7
removed index: 8
removed index: 9
removed index: 11