6

数千列の大きなファイルがあります。Bash で AWK を使用して、特定の列とフィールド セパレータを一度に削除したいと考えています。

このワンライナーで一度に 1 つの列を削除できます (列 3 が削除され、対応するフィールド区切り文字が表示されます)。

awk -vkf=3 -vFS="\t" -vOFS="\t" '{for(i=kf; i<NF;i++){ $i=$(i+1);}; NF--; print}' < Big_File

ただし、一度に複数の列を削除したい...誰かがこれを理解するのを手伝ってくれますか?

4

4 に答える 4

5

awk次のように、シェルから削除する列のリストを渡すことができます。

awk -vkf="3,5,11" ...

次に、awkプログラムでそれを配列に解析します。

split(kf,kf_array,",")

次に、すべての列を調べて、特定の各列が kf_array にあるかどうかをテストし、場合によってはスキップします

他の可能性は、ワンライナーに数回電話することです:-)

于 2012-11-13T14:01:13.163 に答える
4

カミルのアイデアの実装は次のとおりです。

awk -v remove="3,8,5" '
  BEGIN {
    OFS=FS="\t"
    split(remove,a,",")
    for (i in a) b[a[i]]=1
  }                                                          
  {
    j=1
    for (i=1;i<=NF;++i) {
      if (!(i in b)) { 
        $j=$i
        ++j
      }
    }
    NF=j-1
    print
  }
'
于 2012-11-13T14:19:30.367 に答える
3

cutの代わりに使用できる場合awk、これは次のほうが簡単ですcut

たとえば、これはファイルから列 1、3、および 50 以降を取得します。

cut -f1,3,50- file

于 2012-11-13T14:41:46.927 に答える
0

このようなものが動作するはずです:

awk -F'\t' -v remove='3|8|5' '
{
   rec=ofs=""
   for (i=1;i<=NF;i++) {
      if (i !~ "^(" remove ")$" ) {
         rec = rec ofs $i
         ofs = FS
      }
   }
   print rec
}
' file
于 2012-11-14T13:39:55.090 に答える