2012-11-13 2 views
5

私は数千の列を持つ大きなファイルを持っています。 BashのAWKを使って、特定の列とフィールド区切り記号を一度に削除したい。AWKでいくつかの列とフィールドセパレータを一度に削除するにはどうすればよいですか?

私はこのoneliner(コラム3が削除され、それに対応するフィールドの区切りされます)で一度に一つの列を削除することができます。しかし、私は一度に複数の列を削除したい

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

...誰か缶これを理解するのを手助けしますか?

+0

いいえ、それはありません。ここでは、特定の列を選択します。間隔内の列ではありません。 – Bebe

+0

私は異なっています。上記の両方の質問で、両方の範囲を削除するための回答と列のリストが発生します。 – Thor

+0

AWKのために、私はそれを実際に見つけることができませんでした... – Bebe

答えて

2

はカミルのアイデアの実装です:

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 
    } 
' 
+0

ありがとう、しかし、スクリプトはフィールドの区切りを変更し、私は区切り、任意のアイデアとして "タブ"を使用し続けたいですか? – Bebe

+0

@Bebe:真実 - 私はそれを修正しました。 –

+0

それだけです!ありがとうございました! – Bebe

4

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

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

はその後awkプログラムの開発に配列にそれを解析:その後、

split(kf,kf_array,",") 

とすべてスルー行きます列を検索し、各特定の列がkf_arrayに含まれているかどうかをテストし、可能であればスキップします。

その他の可能性は、オンライナーサーバここでアル回:-)

2

あなたがcut代わりのawkを使用することができる場合は、この1つはcutと簡単です:

例えば

cut -f1,3,50- file

0

このような何かが動作するはずです:これは、列1,3、および50からのファイルの上を取得

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